This is an automated email from the ASF dual-hosted git repository.
timoninmaxim pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new b20fe87b897 IGNITE-27030 Add force flag for enabling rolling upgrade
(#12513)
b20fe87b897 is described below
commit b20fe87b89765482a4a714974069e620a4c58045
Author: Aleksandr Chesnokov <[email protected]>
AuthorDate: Thu Nov 13 17:42:59 2025 +0300
IGNITE-27030 Add force flag for enabling rolling upgrade (#12513)
---
.../ignite/util/RollingUpgradeCommandTest.java | 50 ++++++++++++++++++++++
.../RollingUpgradeEnableCommandArg.java | 17 ++++++++
.../rollingupgrade/RollingUpgradeEnableTask.java | 2 +-
.../rollingupgrade/RollingUpgradeProcessor.java | 22 ++++++++--
.../ignite/internal/GridReleaseTypeSelfTest.java | 44 +++++++++++++------
...ridCommandHandlerClusterByClassTest_help.output | 3 +-
...andHandlerClusterByClassWithSSLTest_help.output | 3 +-
7 files changed, 120 insertions(+), 21 deletions(-)
diff --git
a/modules/control-utility/src/test/java/org/apache/ignite/util/RollingUpgradeCommandTest.java
b/modules/control-utility/src/test/java/org/apache/ignite/util/RollingUpgradeCommandTest.java
index 6737103dbd4..b924fb4186f 100644
---
a/modules/control-utility/src/test/java/org/apache/ignite/util/RollingUpgradeCommandTest.java
+++
b/modules/control-utility/src/test/java/org/apache/ignite/util/RollingUpgradeCommandTest.java
@@ -33,6 +33,9 @@ public class RollingUpgradeCommandTest extends
GridCommandHandlerClusterByClassA
/** */
public static final String DISABLE = "disable";
+ /** */
+ public static final String FORCE = "--force";
+
/** */
public static final String ROLLING_UPGRADE = "--rolling-upgrade";
@@ -43,6 +46,14 @@ public class RollingUpgradeCommandTest extends
GridCommandHandlerClusterByClassA
autoConfirmation = true;
}
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ if (crd.context().rollingUpgrade().enabled())
+ crd.context().rollingUpgrade().disable();
+ }
+
/** */
@Test
public void testEnableAndDisable() {
@@ -127,4 +138,43 @@ public class RollingUpgradeCommandTest extends
GridCommandHandlerClusterByClassA
assertTrue(crd.context().rollingUpgrade().enabled());
}
+
+ /** */
+ @Test
+ public void testForceEnable() {
+ IgniteProductVersion curVer =
IgniteProductVersion.fromString(crd.localNode().attribute(ATTR_BUILD_VER));
+
+ String targetVerStr = curVer.major() + "." + (curVer.minor() + 1) +
"." + (curVer.maintenance() + 1);
+ IgniteProductVersion targetVer =
IgniteProductVersion.fromString(targetVerStr);
+
+ int res = execute(ROLLING_UPGRADE, ENABLE, targetVerStr);
+
+ assertEquals(EXIT_CODE_OK, res);
+
+ RollingUpgradeTaskResult taskRes =
(RollingUpgradeTaskResult)lastOperationResult;
+
+ assertNotNull(taskRes.errorMessage());
+ assertTrue(taskRes.errorMessage().contains("Minor version can only be
incremented by 1"));
+ assertNull(taskRes.targetVersion());
+
+ String anotherTargetVerStr = curVer.major() + "." + curVer.minor() +
"." + (curVer.maintenance() + 1);
+
+ execute(ROLLING_UPGRADE, ENABLE, targetVerStr, FORCE);
+
+ taskRes = (RollingUpgradeTaskResult)lastOperationResult;
+ assertNull(taskRes.errorMessage());
+
+ res = execute(ROLLING_UPGRADE, ENABLE, anotherTargetVerStr, FORCE);
+
+ assertEquals(EXIT_CODE_OK, res);
+ taskRes = (RollingUpgradeTaskResult)lastOperationResult;
+
+ assertNotNull(taskRes.errorMessage());
+ assertTrue(taskRes.errorMessage().contains("Rolling upgrade is already
enabled with a different current and target version"));
+
+ assertEquals(curVer, taskRes.currentVersion());
+ assertEquals(targetVer, taskRes.targetVersion());
+
+ assertTrue(crd.context().rollingUpgrade().enabled());
+ }
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableCommandArg.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableCommandArg.java
index 180e7e39d76..16cccf4eafe 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableCommandArg.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableCommandArg.java
@@ -36,6 +36,11 @@ public class RollingUpgradeEnableCommandArg extends
IgniteDataTransferObject {
+ "or one maintenance version higher (e.g. 2.18.0 -> 2.18.1 or 2.18.1
-> 2.19.0)")
private String targetVersion;
+ /** Force flag. */
+ @Argument(description = "Enable rolling upgrade without target version
checks."
+ + " Use only when required, if the upgrade cannot proceed otherwise",
optional = true)
+ private boolean force;
+
/** */
public String targetVersion() {
return targetVersion;
@@ -46,13 +51,25 @@ public class RollingUpgradeEnableCommandArg extends
IgniteDataTransferObject {
this.targetVersion = targetVersion;
}
+ /** */
+ public boolean force() {
+ return force;
+ }
+
+ /** */
+ public void force(boolean force) {
+ this.force = force;
+ }
+
/** {@inheritDoc} */
@Override protected void writeExternalData(ObjectOutput out) throws
IOException {
U.writeString(out, targetVersion);
+ out.writeBoolean(force);
}
/** {@inheritDoc} */
@Override protected void readExternalData(ObjectInput in) throws
IOException, ClassNotFoundException {
targetVersion = U.readString(in);
+ force = in.readBoolean();
}
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableTask.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableTask.java
index 70b279f01de..113e0dc659c 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableTask.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableTask.java
@@ -52,7 +52,7 @@ public class RollingUpgradeEnableTask extends
VisorOneNodeTask<RollingUpgradeEna
RollingUpgradeProcessor proc = ignite.context().rollingUpgrade();
try {
-
proc.enable(IgniteProductVersion.fromString(arg.targetVersion()));
+
proc.enable(IgniteProductVersion.fromString(arg.targetVersion()), arg.force());
IgnitePair<IgniteProductVersion> rollUpVers = proc.versions();
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
index 14af99193ab..7e5be3b10a5 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java
@@ -155,6 +155,8 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
* This method can only be called on coordinator node with {@link
TcpDiscoverySpi}.
*
* @param target Target version.
+ * @param force If {@code true}, skips target version compatibility checks
and forcibly enables rolling upgrade.
+ * This flag does not override an already active upgrade
configuration.
* @throws IgniteCheckedException If:
* <ul>
* <li>The current and target versions are incompatible;</li>
@@ -163,7 +165,7 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
* <li>The distributed metastorage is not ready;</li>
* </ul>
*/
- public void enable(IgniteProductVersion target) throws
IgniteCheckedException {
+ public void enable(IgniteProductVersion target, boolean force) throws
IgniteCheckedException {
if (startLatch.getCount() > 0)
throw new IgniteCheckedException("Cannot enable rolling upgrade:
processor has not been started yet");
@@ -179,7 +181,7 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
String curBuildVer =
ctx.discovery().localNode().attribute(ATTR_BUILD_VER);
IgniteProductVersion curVer =
IgniteProductVersion.fromString(curBuildVer);
- if (!checkVersionsForEnabling(curVer, target))
+ if (!checkVersionsForEnabling(curVer, target, force))
return;
IgnitePair<IgniteProductVersion> newPair = F.pair(curVer, target);
@@ -278,10 +280,14 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
*
* @param cur Current cluster version.
* @param target Target cluster version.
- * @return {@code false} if there is no need to update versions {@code
true} otherwise.
+ * @param force Force flag to skip version checks.
* @throws IgniteCheckedException If versions are incorrect.
*/
- private boolean checkVersionsForEnabling(IgniteProductVersion cur,
IgniteProductVersion target) throws IgniteCheckedException {
+ private boolean checkVersionsForEnabling(
+ IgniteProductVersion cur,
+ IgniteProductVersion target,
+ boolean force
+ ) throws IgniteCheckedException {
IgnitePair<IgniteProductVersion> oldVerPair = rollUpVers;
if (oldVerPair != null) {
if (oldVerPair.get1().equals(cur) &&
oldVerPair.get2().equals(target))
@@ -291,6 +297,14 @@ public class RollingUpgradeProcessor extends
GridProcessorAdapter implements Dis
oldVerPair.get1() + " , " + oldVerPair.get2());
}
+ if (force) {
+ if (log.isInfoEnabled())
+ log.info("Skipping version compatibility check for rolling
upgrade due to force flag "
+ + "[currentVer=" + cur + ", targetVer=" + target + ']');
+
+ return true;
+ }
+
if (cur.major() != target.major())
throw new IgniteCheckedException("Major versions are different");
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/GridReleaseTypeSelfTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/GridReleaseTypeSelfTest.java
index 36035e32b81..afbfef1bd75 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/GridReleaseTypeSelfTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/GridReleaseTypeSelfTest.java
@@ -145,16 +145,26 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
/** */
@Test
public void testForwardRollingUpgrade() throws Exception {
- cleanPersistenceDir();
- IgniteEx ign0 = startGrid(0, "2.18.0", false);
- IgniteEx ign1 = startGrid(1, "2.18.0", client);
- IgniteEx ign2 = startGrid(2, "2.18.0", client);
+ doTestRollingUpgrade("2.18.0", "2.18.1", false);
+ }
+
+ /** */
+ @Test
+ public void testForceRollingUpgrade() throws Exception {
+ doTestRollingUpgrade("2.18.0", "2.19.1", true);
+ }
+
+ /** Performs full rolling upgrade scenario. */
+ private void doTestRollingUpgrade(String curVer, String targetVer, boolean
force) throws Exception {
+ IgniteEx ign0 = startGrid(0, curVer, false);
+ IgniteEx ign1 = startGrid(1, curVer, client);
+ IgniteEx ign2 = startGrid(2, curVer, client);
assertClusterSize(3);
- assertRemoteRejected(() -> startGrid(3, "2.18.1", client));
+ assertRemoteRejected(() -> startGrid(3, targetVer, client));
- configureRollingUpgradeVersion(ign0, "2.18.1");
+ configureRollingUpgradeVersion(ign0, targetVer, force);
for (int i = 0; i < 3; i++) {
int finalI = i;
@@ -165,7 +175,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
assertClusterSize(2);
- startGrid(2, "2.18.1", client);
+ startGrid(2, targetVer, client);
assertClusterSize(3);
@@ -173,7 +183,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
assertClusterSize(2);
- startGrid(1, "2.18.1", client);
+ startGrid(1, targetVer, client);
assertClusterSize(3);
@@ -181,7 +191,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
assertClusterSize(2);
- startGrid(0, "2.18.1", false);
+ startGrid(0, targetVer, false);
assertClusterSize(3);
@@ -195,7 +205,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
assertFalse(grid(i).context().rollingUpgrade().enabled());
}
- assertRemoteRejected(() -> startGrid(3, "2.18.0", client));
+ assertRemoteRejected(() -> startGrid(3, curVer, client));
}
/** */
@@ -315,7 +325,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
IgnitePair<IgniteProductVersion> newPair =
F.pair(IgniteProductVersion.fromString("2.18.0"),
IgniteProductVersion.fromString("2.19.0"));
- grid0.context().rollingUpgrade().enable(newPair.get2());
+ grid0.context().rollingUpgrade().enable(newPair.get2(), false);
assertEnablingFails(grid0, "2.18.1", "Rolling upgrade is already
enabled with a different current and target version");
@@ -335,7 +345,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
*/
private void assertEnablingFails(IgniteEx ex, String ver, String errMsg) {
Throwable e = assertThrows(log,
- () ->
ex.context().rollingUpgrade().enable(IgniteProductVersion.fromString(ver)),
+ () ->
ex.context().rollingUpgrade().enable(IgniteProductVersion.fromString(ver),
false),
IgniteException.class,
null);
@@ -470,10 +480,16 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
return ign;
}
+ /** */
+ private void configureRollingUpgradeVersion(IgniteEx grid, String ver)
throws IgniteCheckedException {
+ configureRollingUpgradeVersion(grid, ver, false);
+ }
+
/**
* @param ver Version for rolling upgrade support.
+ * @param force Force rolling upgrade.
*/
- private void configureRollingUpgradeVersion(IgniteEx grid, String ver)
throws IgniteCheckedException {
+ private void configureRollingUpgradeVersion(IgniteEx grid, String ver,
boolean force) throws IgniteCheckedException {
if (ver == null) {
grid.context().rollingUpgrade().disable();
return;
@@ -481,7 +497,7 @@ public class GridReleaseTypeSelfTest extends
GridCommonAbstractTest {
IgniteProductVersion target = IgniteProductVersion.fromString(ver);
- grid.context().rollingUpgrade().enable(target);
+ grid.context().rollingUpgrade().enable(target, force);
}
/**
diff --git
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index 06a5226d291..9bf90f38eac 100644
---
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -373,10 +373,11 @@ If the file name isn't specified the output file name is:
'<typeId>.bin':
[EXPERIMENTAL]
Enable rolling upgrade mode. It allows cluster with mixed-version nodes:
- control.(sh|bat) --rolling-upgrade enable target_version
+ control.(sh|bat) --rolling-upgrade enable target_version [--force]
Parameters:
target_version - Target Ignite version. The target version can be one
minor higher if its maintenance version is zero, or one maintenance version
higher (e.g. 2.18.0 -> 2.18.1 or 2.18.1 -> 2.19.0).
+ --force - Enable rolling upgrade without target version
checks. Use only when required, if the upgrade cannot proceed otherwise.
[EXPERIMENTAL]
Disable rolling upgrade mode. All nodes in the cluster must be running the
same version:
diff --git
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index a3a7da449d8..21cef2d908e 100644
---
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -373,10 +373,11 @@ If the file name isn't specified the output file name is:
'<typeId>.bin':
[EXPERIMENTAL]
Enable rolling upgrade mode. It allows cluster with mixed-version nodes:
- control.(sh|bat) --rolling-upgrade enable target_version
+ control.(sh|bat) --rolling-upgrade enable target_version [--force]
Parameters:
target_version - Target Ignite version. The target version can be one
minor higher if its maintenance version is zero, or one maintenance version
higher (e.g. 2.18.0 -> 2.18.1 or 2.18.1 -> 2.19.0).
+ --force - Enable rolling upgrade without target version
checks. Use only when required, if the upgrade cannot proceed otherwise.
[EXPERIMENTAL]
Disable rolling upgrade mode. All nodes in the cluster must be running the
same version: