Skip to content

Commit 3c4ea35

Browse files
committed
IGNITE-27030 Add force flag
1 parent 36cbb27 commit 3c4ea35

7 files changed

Lines changed: 112 additions & 39 deletions

File tree

modules/control-utility/src/test/java/org/apache/ignite/util/RollingUpgradeCommandTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ public class RollingUpgradeCommandTest extends GridCommandHandlerClusterByClassA
3333
/** */
3434
public static final String DISABLE = "disable";
3535

36+
/** */
37+
public static final String FORCE = "--force";
38+
3639
/** */
3740
public static final String ROLLING_UPGRADE = "--rolling-upgrade";
3841

@@ -43,6 +46,14 @@ public class RollingUpgradeCommandTest extends GridCommandHandlerClusterByClassA
4346
autoConfirmation = true;
4447
}
4548

49+
/** {@inheritDoc} */
50+
@Override protected void afterTest() throws Exception {
51+
super.afterTest();
52+
53+
if (crd.context().rollingUpgrade().enabled())
54+
crd.context().rollingUpgrade().disable();
55+
}
56+
4657
/** */
4758
@Test
4859
public void testEnableAndDisable() {
@@ -127,4 +138,30 @@ public void testEnableWithDifferentTargetVersions() {
127138

128139
assertTrue(crd.context().rollingUpgrade().enabled());
129140
}
141+
142+
/** */
143+
@Test
144+
public void testForceEnable() {
145+
IgniteProductVersion curVer = IgniteProductVersion.fromString(crd.localNode().attribute(ATTR_BUILD_VER));
146+
147+
String targetVerStr = curVer.major() + "." + (curVer.minor() + 1) + "." + (curVer.maintenance() + 1);
148+
IgniteProductVersion targetVer = IgniteProductVersion.fromString(targetVerStr);
149+
150+
execute(ROLLING_UPGRADE, ENABLE, targetVerStr, FORCE);
151+
152+
String anotherTargetVerStr = curVer.major() + "." + curVer.minor() + "." + (curVer.maintenance() + 1);
153+
154+
int res = execute(ROLLING_UPGRADE, ENABLE, anotherTargetVerStr, FORCE);
155+
156+
assertEquals(EXIT_CODE_OK, res);
157+
RollingUpgradeTaskResult taskRes = (RollingUpgradeTaskResult)lastOperationResult;
158+
159+
assertNotNull(taskRes.errorMessage());
160+
assertTrue(taskRes.errorMessage().contains("Rolling upgrade is already enabled with a different current and target version"));
161+
162+
assertEquals(curVer, taskRes.currentVersion());
163+
assertEquals(targetVer, taskRes.targetVersion());
164+
165+
assertTrue(crd.context().rollingUpgrade().enabled());
166+
}
130167
}

modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableCommandArg.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public class RollingUpgradeEnableCommandArg extends IgniteDataTransferObject {
3636
+ "or one maintenance version higher (e.g. 2.18.0 -> 2.18.1 or 2.18.1 -> 2.19.0)")
3737
private String targetVersion;
3838

39+
/** Force flag. */
40+
@Argument(description = "Enable rolling upgrade without target version checks", optional = true)
41+
private boolean force;
42+
3943
/** */
4044
public String targetVersion() {
4145
return targetVersion;
@@ -46,13 +50,25 @@ public void targetVersion(String targetVersion) {
4650
this.targetVersion = targetVersion;
4751
}
4852

53+
/** */
54+
public boolean force() {
55+
return force;
56+
}
57+
58+
/** */
59+
public void force(boolean force) {
60+
this.force = force;
61+
}
62+
4963
/** {@inheritDoc} */
5064
@Override protected void writeExternalData(ObjectOutput out) throws IOException {
5165
U.writeString(out, targetVersion);
66+
out.writeBoolean(force);
5267
}
5368

5469
/** {@inheritDoc} */
5570
@Override protected void readExternalData(ObjectInput in) throws IOException, ClassNotFoundException {
5671
targetVersion = U.readString(in);
72+
force = in.readBoolean();
5773
}
5874
}

modules/core/src/main/java/org/apache/ignite/internal/management/rollingupgrade/RollingUpgradeEnableTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ protected RollingUpgradeEnableJob(RollingUpgradeEnableCommandArg arg, boolean de
5252
RollingUpgradeProcessor proc = ignite.context().rollingUpgrade();
5353

5454
try {
55-
proc.enable(IgniteProductVersion.fromString(arg.targetVersion()));
55+
proc.enable(IgniteProductVersion.fromString(arg.targetVersion()), arg.force());
5656

5757
IgnitePair<IgniteProductVersion> rollUpVers = proc.versions();
5858

modules/core/src/main/java/org/apache/ignite/internal/processors/rollingupgrade/RollingUpgradeProcessor.java

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,22 @@ public RollingUpgradeProcessor(GridKernalContext ctx) {
150150
return new IgniteNodeValidationResult(node.id(), errMsg);
151151
}
152152

153+
/**
154+
* Enables rolling upgrade with the specified target version.
155+
* @param target Target version.
156+
* @see #enable(IgniteProductVersion, boolean)
157+
*/
158+
public void enable(IgniteProductVersion target) throws IgniteCheckedException {
159+
enable(target, false);
160+
}
161+
153162
/**
154163
* Enables rolling upgrade with specified target version.
155164
* This method can only be called on coordinator node with {@link TcpDiscoverySpi}.
156165
*
157166
* @param target Target version.
167+
* @param force If {@code true}, skips target version compatibility validation and forcibly enables rolling upgrade.
168+
* This flag does not override an already active upgrade configuration.
158169
* @throws IgniteCheckedException If:
159170
* <ul>
160171
* <li>The current and target versions are incompatible;</li>
@@ -163,7 +174,7 @@ public RollingUpgradeProcessor(GridKernalContext ctx) {
163174
* <li>The distributed metastorage is not ready;</li>
164175
* </ul>
165176
*/
166-
public void enable(IgniteProductVersion target) throws IgniteCheckedException {
177+
public void enable(IgniteProductVersion target, boolean force) throws IgniteCheckedException {
167178
if (startLatch.getCount() > 0)
168179
throw new IgniteCheckedException("Cannot enable rolling upgrade: processor has not been started yet");
169180

@@ -179,13 +190,22 @@ public void enable(IgniteProductVersion target) throws IgniteCheckedException {
179190
String curBuildVer = ctx.discovery().localNode().attribute(ATTR_BUILD_VER);
180191
IgniteProductVersion curVer = IgniteProductVersion.fromString(curBuildVer);
181192

182-
if (!checkVersionsForEnabling(curVer, target))
183-
return;
193+
IgnitePair<IgniteProductVersion> oldVerPair = rollUpVers;
194+
if (oldVerPair != null) {
195+
if (oldVerPair.get1().equals(curVer) && oldVerPair.get2().equals(target))
196+
return;
197+
198+
throw new IgniteCheckedException("Rolling upgrade is already enabled with a different current and target version: " +
199+
oldVerPair.get1() + " , " + oldVerPair.get2());
200+
}
201+
202+
if (!force)
203+
checkVersionsForEnabling(curVer, target);
184204

185205
IgnitePair<IgniteProductVersion> newPair = F.pair(curVer, target);
186206

187207
if (!metastorage.compareAndSet(ROLLING_UPGRADE_VERSIONS_KEY, null, newPair)) {
188-
IgnitePair<IgniteProductVersion> oldVerPair = metastorage.read(ROLLING_UPGRADE_VERSIONS_KEY);
208+
oldVerPair = metastorage.read(ROLLING_UPGRADE_VERSIONS_KEY);
189209

190210
if (newPair.equals(oldVerPair))
191211
return;
@@ -278,32 +298,20 @@ public boolean enabled() {
278298
*
279299
* @param cur Current cluster version.
280300
* @param target Target cluster version.
281-
* @return {@code false} if there is no need to update versions {@code true} otherwise.
282301
* @throws IgniteCheckedException If versions are incorrect.
283302
*/
284-
private boolean checkVersionsForEnabling(IgniteProductVersion cur, IgniteProductVersion target) throws IgniteCheckedException {
285-
IgnitePair<IgniteProductVersion> oldVerPair = rollUpVers;
286-
if (oldVerPair != null) {
287-
if (oldVerPair.get1().equals(cur) && oldVerPair.get2().equals(target))
288-
return false;
289-
290-
throw new IgniteCheckedException("Rolling upgrade is already enabled with a different current and target version: " +
291-
oldVerPair.get1() + " , " + oldVerPair.get2());
292-
}
293-
303+
private void checkVersionsForEnabling(IgniteProductVersion cur, IgniteProductVersion target) throws IgniteCheckedException {
294304
if (cur.major() != target.major())
295305
throw new IgniteCheckedException("Major versions are different");
296306

297307
if (cur.minor() != target.minor()) {
298308
if (target.minor() == cur.minor() + 1 && target.maintenance() == 0)
299-
return true;
309+
return;
300310

301311
throw new IgniteCheckedException("Minor version can only be incremented by 1");
302312
}
303313

304314
if (cur.maintenance() + 1 != target.maintenance())
305315
throw new IgniteCheckedException("Patch version can only be incremented by 1");
306-
307-
return true;
308316
}
309317
}

modules/core/src/test/java/org/apache/ignite/internal/GridReleaseTypeSelfTest.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,26 @@ public void testThreeCompatibleVersions() throws Exception {
145145
/** */
146146
@Test
147147
public void testForwardRollingUpgrade() throws Exception {
148-
cleanPersistenceDir();
149-
IgniteEx ign0 = startGrid(0, "2.18.0", false);
150-
IgniteEx ign1 = startGrid(1, "2.18.0", client);
151-
IgniteEx ign2 = startGrid(2, "2.18.0", client);
148+
doTestRollingUpgrade("2.18.0", "2.18.1", false);
149+
}
150+
151+
/** */
152+
@Test
153+
public void testForceRollingUpgrade() throws Exception {
154+
doTestRollingUpgrade("2.18.0", "2.19.1", true);
155+
}
156+
157+
/** Performs full rolling upgrade scenario. */
158+
private void doTestRollingUpgrade(String curVer, String targetVer, boolean force) throws Exception {
159+
IgniteEx ign0 = startGrid(0, curVer, false);
160+
IgniteEx ign1 = startGrid(1, curVer, client);
161+
IgniteEx ign2 = startGrid(2, curVer, client);
152162

153163
assertClusterSize(3);
154164

155-
assertRemoteRejected(() -> startGrid(3, "2.18.1", client));
165+
assertRemoteRejected(() -> startGrid(3, targetVer, client));
156166

157-
configureRollingUpgradeVersion(ign0, "2.18.1");
167+
configureRollingUpgradeVersion(ign0, targetVer, force);
158168

159169
for (int i = 0; i < 3; i++) {
160170
int finalI = i;
@@ -164,25 +174,19 @@ public void testForwardRollingUpgrade() throws Exception {
164174
ign2.close();
165175

166176
assertClusterSize(2);
167-
168-
startGrid(2, "2.18.1", client);
169-
177+
startGrid(2, targetVer, client);
170178
assertClusterSize(3);
171179

172180
ign1.close();
173181

174182
assertClusterSize(2);
175-
176-
startGrid(1, "2.18.1", client);
177-
183+
startGrid(1, targetVer, client);
178184
assertClusterSize(3);
179185

180186
ign0.close();
181187

182188
assertClusterSize(2);
183-
184-
startGrid(0, "2.18.1", false);
185-
189+
startGrid(0, targetVer, false);
186190
assertClusterSize(3);
187191

188192
if (client)
@@ -195,7 +199,7 @@ public void testForwardRollingUpgrade() throws Exception {
195199
assertFalse(grid(i).context().rollingUpgrade().enabled());
196200
}
197201

198-
assertRemoteRejected(() -> startGrid(3, "2.18.0", client));
202+
assertRemoteRejected(() -> startGrid(3, curVer, client));
199203
}
200204

201205
/** */
@@ -470,18 +474,24 @@ private IgniteEx startGrid(int idx, String ver, boolean isClient, UnaryOperator<
470474
return ign;
471475
}
472476

477+
/** */
478+
private void configureRollingUpgradeVersion(IgniteEx grid, String ver) throws IgniteCheckedException {
479+
configureRollingUpgradeVersion(grid, ver, false);
480+
}
481+
473482
/**
474483
* @param ver Version for rolling upgrade support.
484+
* @param force Force rolling upgrade.
475485
*/
476-
private void configureRollingUpgradeVersion(IgniteEx grid, String ver) throws IgniteCheckedException {
486+
private void configureRollingUpgradeVersion(IgniteEx grid, String ver, boolean force) throws IgniteCheckedException {
477487
if (ver == null) {
478488
grid.context().rollingUpgrade().disable();
479489
return;
480490
}
481491

482492
IgniteProductVersion target = IgniteProductVersion.fromString(ver);
483493

484-
grid.context().rollingUpgrade().enable(target);
494+
grid.context().rollingUpgrade().enable(target, force);
485495
}
486496

487497
/**

modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,11 @@ If the file name isn't specified the output file name is: '<typeId>.bin':
373373

374374
[EXPERIMENTAL]
375375
Enable rolling upgrade mode. It allows cluster with mixed-version nodes:
376-
control.(sh|bat) --rolling-upgrade enable target_version
376+
control.(sh|bat) --rolling-upgrade enable target_version --force
377377

378378
Parameters:
379379
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).
380+
--force - Enable rolling upgrade without target version checks.
380381

381382
[EXPERIMENTAL]
382383
Disable rolling upgrade mode. All nodes in the cluster must be running the same version:

modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,11 @@ If the file name isn't specified the output file name is: '<typeId>.bin':
373373

374374
[EXPERIMENTAL]
375375
Enable rolling upgrade mode. It allows cluster with mixed-version nodes:
376-
control.(sh|bat) --rolling-upgrade enable target_version
376+
control.(sh|bat) --rolling-upgrade enable target_version --force
377377

378378
Parameters:
379379
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).
380+
--force - Enable rolling upgrade without target version checks.
380381

381382
[EXPERIMENTAL]
382383
Disable rolling upgrade mode. All nodes in the cluster must be running the same version:

0 commit comments

Comments
 (0)