chesnokoff commented on code in PR #12301:
URL: https://github.com/apache/ignite/pull/12301#discussion_r2324304146
##########
modules/core/src/main/java/org/apache/ignite/internal/processors/nodevalidation/OsDiscoveryNodeValidationProcessor.java:
##########
@@ -43,31 +54,72 @@ public OsDiscoveryNodeValidationProcessor(GridKernalContext
ctx) {
@Nullable @Override public IgniteNodeValidationResult
validateNode(ClusterNode node) {
ClusterNode locNode = ctx.discovery().localNode();
- // Check version.
String locBuildVer = locNode.attribute(ATTR_BUILD_VER);
String rmtBuildVer = node.attribute(ATTR_BUILD_VER);
- if (!Objects.equals(rmtBuildVer, locBuildVer)) {
- // OS nodes don't support rolling updates.
- if (!locBuildVer.equals(rmtBuildVer)) {
- String errMsg = "Local node and remote node have different
version numbers " +
- "(node will not join, Ignite does not support rolling
updates, " +
- "so versions must be exactly the same) " +
- "[locBuildVer=" + locBuildVer + ", rmtBuildVer=" +
rmtBuildVer +
- ", locNodeAddrs=" + U.addressesAsString(locNode) +
- ", rmtNodeAddrs=" + U.addressesAsString(node) +
- ", locNodeId=" + locNode.id() + ", rmtNodeId=" + node.id()
+ ']';
-
- LT.warn(log, errMsg);
-
- // Always output in debug.
- if (log.isDebugEnabled())
- log.debug(errMsg);
-
- return new IgniteNodeValidationResult(node.id(), errMsg);
- }
+ IgniteProductVersion locVer =
IgniteProductVersion.fromString(locBuildVer);
+ IgniteProductVersion rmtVer =
IgniteProductVersion.fromString(rmtBuildVer);
+
+ if (!isRollingUpgradeEligible(locVer, rmtVer)) {
+ String errMsg = "Remote node rejected due to incompatible version
for cluster join.\n"
+ + "Remote node info:\n"
+ + " - Version : " + rmtBuildVer + "\n"
+ + " - Addresses : " + U.addressesAsString(node) + "\n"
+ + " - Node ID : " + node.id() + "\n"
+ + "Local node info:\n"
+ + " - Version : " + locBuildVer + "\n"
+ + " - Addresses : " + U.addressesAsString(locNode) + "\n"
+ + " - Node ID : " + locNode.id() + "\n"
+ + "Allowed versions for joining:\n"
+ + " - " + locVer.major() + '.' + locVer.minor() + ".X\n"
+ + " - " + locVer.major() + '.' + (locVer.minor() + 1) + ".X\n"
+ + " - " + locVer.major() + '.' + (locVer.minor() - 1) + ".X";
+
+ LT.warn(log, errMsg);
+
+ if (log.isDebugEnabled())
+ log.debug(errMsg);
+
+ return new IgniteNodeValidationResult(node.id(), errMsg);
}
return null;
}
+
+ /**
+ * Determines whether the remote node's version is eligible for rolling
upgrade with the local node.
+ * <p>
+ * A remote version is considered eligible if:
+ * <ul>
+ * <li>It exactly matches the local version; or</li>
+ * <li>It has the same major version as the local node and the
difference in minor versions is within {@link #MAX_MINOR_DIFF}.</li>
+ * </ul>
+ *
+ * @param locVer Local node's Ignite product version.
+ * @param rmtVer Remote node's Ignite product version.
+ * @return {@code true} if the remote version is compatible and eligible
for rolling upgrade, {@code false} otherwise.
+ */
+ private boolean isRollingUpgradeEligible(IgniteProductVersion locVer,
IgniteProductVersion rmtVer) {
+ if (locVer.major() != rmtVer.major())
+ return false;
+
+ if (locVer.minor() == rmtVer.minor())
+ return true;
+
+ boolean enableCheck =
IgniteSystemProperties.getBoolean(IGNITE_ROLLING_UPGRADE_VERSION_CHECK);
+ if (!enableCheck)
+ return false;
+
+ Set<Byte> versions = ctx.discovery().allNodes().stream()
+ .map(node ->
IgniteProductVersion.fromString(node.attribute(ATTR_BUILD_VER)).minor())
+ .collect(Collectors.toSet());
Review Comment:
Previous patch used field to store available version only first time. But
there are two problems:
1) If we change coordinator to node with higher version, it may accept +2
version so there is a probability to have three versions of nodes in cluster
2) If +1 version node was accepted, after that it disconnected and we want
to add -1 version it will be rejected
So we have to scan available versions in `discovery().allNodes()` every time
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]