Skip to content

Commit b090ee5

Browse files
authored
IGNITE-26748 Add rolling upgrade commands for control.sh (#12494)
1 parent 74e8f9f commit b090ee5

File tree

13 files changed

+645
-0
lines changed

13 files changed

+645
-0
lines changed

modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
import org.apache.ignite.internal.management.metric.MetricCommand;
7777
import org.apache.ignite.internal.management.performancestatistics.PerformanceStatisticsCommand;
7878
import org.apache.ignite.internal.management.property.PropertyCommand;
79+
import org.apache.ignite.internal.management.rollingupgrade.RollingUpgradeCommand;
80+
import org.apache.ignite.internal.management.rollingupgrade.RollingUpgradeEnableCommand;
7981
import org.apache.ignite.internal.management.snapshot.SnapshotCommand;
8082
import org.apache.ignite.internal.management.snapshot.SnapshotRestoreCommand;
8183
import org.apache.ignite.internal.management.tx.TxCommand;
@@ -516,6 +518,8 @@ else if (cmd.getClass() == EncryptionChangeMasterKeyCommand.class)
516518
cmdText = F.concat(cmdText, "masterKeyName1");
517519
else if (cmd.getClass() == EncryptionChangeCacheKeyCommand.class)
518520
cmdText = F.concat(cmdText, "cacheGroup1");
521+
else if (cmd.getClass() == RollingUpgradeEnableCommand.class)
522+
cmdText = F.concat(cmdText, "2.18.0");
519523
else if (cmd.getClass() == SnapshotRestoreCommand.class)
520524
cmdText = F.concat(cmdText, "snp1");
521525
else if (cmd.getClass() == MetaUpdateCommand.class)
@@ -1391,6 +1395,7 @@ private boolean requireArgs(Class<?> cmd) {
13911395
cmd == MetaCommand.class ||
13921396
cmd == WarmUpCommand.class ||
13931397
cmd == PropertyCommand.class ||
1398+
cmd == RollingUpgradeCommand.class ||
13941399
cmd == SystemViewCommand.class ||
13951400
cmd == MetricCommand.class ||
13961401
cmd == DefragmentationCommand.class ||

modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite2.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.apache.ignite.util.IdleVerifyDumpTest;
3838
import org.apache.ignite.util.MetricCommandTest;
3939
import org.apache.ignite.util.PerformanceStatisticsCommandTest;
40+
import org.apache.ignite.util.RollingUpgradeCommandTest;
4041
import org.apache.ignite.util.SystemViewCommandTest;
4142
import org.junit.runner.RunWith;
4243
import org.junit.runners.Suite;
@@ -63,6 +64,7 @@
6364
GridCommandHandlerConsistencySensitiveTest.class,
6465
GridCommandHandlerConsistencyRepairCorrectnessAtomicTest.class,
6566

67+
RollingUpgradeCommandTest.class,
6668
SystemViewCommandTest.class,
6769
MetricCommandTest.class,
6870
PerformanceStatisticsCommandTest.class,
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.util;
19+
20+
import org.apache.ignite.internal.management.rollingupgrade.RollingUpgradeCommand;
21+
import org.apache.ignite.internal.management.rollingupgrade.RollingUpgradeTaskResult;
22+
import org.apache.ignite.lang.IgniteProductVersion;
23+
import org.junit.Test;
24+
25+
import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER;
26+
import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
27+
28+
/** Tests {@link RollingUpgradeCommand} command. */
29+
public class RollingUpgradeCommandTest extends GridCommandHandlerClusterByClassAbstractTest {
30+
/** */
31+
public static final String ENABLE = "enable";
32+
33+
/** */
34+
public static final String DISABLE = "disable";
35+
36+
/** */
37+
public static final String ROLLING_UPGRADE = "--rolling-upgrade";
38+
39+
/** {@inheritDoc} */
40+
@Override protected void beforeTestsStarted() throws Exception {
41+
super.beforeTestsStarted();
42+
43+
autoConfirmation = true;
44+
}
45+
46+
/** */
47+
@Test
48+
public void testEnableAndDisable() {
49+
IgniteProductVersion curVer = IgniteProductVersion.fromString(crd.localNode().attribute(ATTR_BUILD_VER));
50+
51+
String targetVerStr = curVer.major() + "." + (curVer.minor() + 1) + ".0";
52+
IgniteProductVersion targetVer = IgniteProductVersion.fromString(targetVerStr);
53+
54+
int res = execute(ROLLING_UPGRADE, ENABLE, targetVerStr);
55+
56+
assertEquals(EXIT_CODE_OK, res);
57+
58+
RollingUpgradeTaskResult taskRes = (RollingUpgradeTaskResult)lastOperationResult;
59+
60+
assertNull(taskRes.errorMessage());
61+
assertEquals(curVer, taskRes.currentVersion());
62+
assertEquals(targetVer, taskRes.targetVersion());
63+
64+
assertTrue(crd.context().rollingUpgrade().enabled());
65+
66+
res = execute(ROLLING_UPGRADE, DISABLE);
67+
68+
assertEquals(EXIT_CODE_OK, res);
69+
70+
taskRes = (RollingUpgradeTaskResult)lastOperationResult;
71+
72+
assertNull(taskRes.errorMessage());
73+
assertEquals(curVer, taskRes.currentVersion());
74+
assertNull(taskRes.targetVersion());
75+
76+
assertFalse(crd.context().rollingUpgrade().enabled());
77+
}
78+
79+
/** */
80+
@Test
81+
public void testDoubleDisable() {
82+
IgniteProductVersion curVer = IgniteProductVersion.fromString(crd.localNode().attribute(ATTR_BUILD_VER));
83+
84+
int res = execute(ROLLING_UPGRADE, DISABLE);
85+
86+
assertEquals(EXIT_CODE_OK, res);
87+
RollingUpgradeTaskResult taskRes = (RollingUpgradeTaskResult)lastOperationResult;
88+
89+
assertEquals(curVer, taskRes.currentVersion());
90+
assertNull(taskRes.targetVersion());
91+
assertNull(taskRes.errorMessage());
92+
93+
res = execute(ROLLING_UPGRADE, DISABLE);
94+
95+
assertEquals(EXIT_CODE_OK, res);
96+
taskRes = (RollingUpgradeTaskResult)lastOperationResult;
97+
98+
assertNull(taskRes.errorMessage());
99+
assertEquals(curVer, taskRes.currentVersion());
100+
assertNull(taskRes.targetVersion());
101+
102+
assertFalse(crd.context().rollingUpgrade().enabled());
103+
}
104+
105+
/** */
106+
@Test
107+
public void testEnableWithDifferentTargetVersions() {
108+
IgniteProductVersion curVer = IgniteProductVersion.fromString(crd.localNode().attribute(ATTR_BUILD_VER));
109+
110+
String targetVerStr = curVer.major() + "." + (curVer.minor() + 1) + ".0";
111+
IgniteProductVersion targetVer = IgniteProductVersion.fromString(targetVerStr);
112+
113+
execute(ROLLING_UPGRADE, ENABLE, targetVerStr);
114+
115+
String anotherTargetVerStr = curVer.major() + "." + curVer.minor() + "." + (curVer.maintenance() + 1);
116+
117+
int res = execute(ROLLING_UPGRADE, ENABLE, anotherTargetVerStr);
118+
119+
assertEquals(EXIT_CODE_OK, res);
120+
RollingUpgradeTaskResult taskRes = (RollingUpgradeTaskResult)lastOperationResult;
121+
122+
assertNotNull(taskRes.errorMessage());
123+
assertTrue(taskRes.errorMessage().contains("Rolling upgrade is already enabled with a different current and target version"));
124+
125+
assertEquals(curVer, taskRes.currentVersion());
126+
assertEquals(targetVer, taskRes.targetVersion());
127+
128+
assertTrue(crd.context().rollingUpgrade().enabled());
129+
}
130+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.ignite.internal.management.performancestatistics.PerformanceStatisticsCommand;
3535
import org.apache.ignite.internal.management.persistence.PersistenceCommand;
3636
import org.apache.ignite.internal.management.property.PropertyCommand;
37+
import org.apache.ignite.internal.management.rollingupgrade.RollingUpgradeCommand;
3738
import org.apache.ignite.internal.management.snapshot.SnapshotCommand;
3839
import org.apache.ignite.internal.management.tracing.TracingConfigurationCommand;
3940
import org.apache.ignite.internal.management.tx.TxCommand;
@@ -67,6 +68,7 @@ public IgniteCommandRegistry() {
6768
new TracingConfigurationCommand(),
6869
new WarmUpCommand(),
6970
new PropertyCommand(),
71+
new RollingUpgradeCommand(),
7072
new SystemViewCommand(),
7173
new MetricCommand(),
7274
new PersistenceCommand(),
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.management.rollingupgrade;
19+
20+
import org.apache.ignite.internal.management.api.CommandRegistryImpl;
21+
22+
/** Rolling upgrade commands. */
23+
public class RollingUpgradeCommand extends CommandRegistryImpl {
24+
/** */
25+
public RollingUpgradeCommand() {
26+
super(
27+
new RollingUpgradeEnableCommand(),
28+
new RollingUpgradeDisableCommand()
29+
);
30+
}
31+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.management.rollingupgrade;
19+
20+
import java.util.Collection;
21+
import java.util.function.Consumer;
22+
import org.apache.ignite.IgniteException;
23+
import org.apache.ignite.cluster.ClusterNode;
24+
import org.apache.ignite.internal.management.api.ComputeCommand;
25+
import org.apache.ignite.internal.management.api.NoArg;
26+
import org.apache.ignite.lang.IgniteExperimental;
27+
28+
import static org.apache.ignite.internal.management.api.CommandUtils.coordinatorOrNull;
29+
30+
/** Command to disable rolling upgrade mode. */
31+
@IgniteExperimental
32+
public class RollingUpgradeDisableCommand implements ComputeCommand<NoArg, RollingUpgradeTaskResult> {
33+
/** {@inheritDoc} */
34+
@Override public String description() {
35+
return "Disable rolling upgrade mode. All nodes in the cluster must be running the same version";
36+
}
37+
38+
/** {@inheritDoc} */
39+
@Override public Class<NoArg> argClass() {
40+
return NoArg.class;
41+
}
42+
43+
/** {@inheritDoc} */
44+
@Override public Class<RollingUpgradeDisableTask> taskClass() {
45+
return RollingUpgradeDisableTask.class;
46+
}
47+
48+
/** {@inheritDoc} */
49+
@Override public void printResult(NoArg arg, RollingUpgradeTaskResult res, Consumer<String> printer) {
50+
if (res.errorMessage() != null) {
51+
printer.accept("Failed to disable rolling upgrade: " + res.errorMessage());
52+
return;
53+
}
54+
55+
printer.accept("Rolling upgrade disabled [currentVersion=" + res.currentVersion() + ']');
56+
}
57+
58+
/** {@inheritDoc} */
59+
@Override public Collection<ClusterNode> nodes(Collection<ClusterNode> nodes, NoArg arg) {
60+
Collection<ClusterNode> coordinator = coordinatorOrNull(nodes);
61+
62+
if (coordinator == null)
63+
throw new IgniteException("Could not find coordinator among nodes: " + nodes);
64+
65+
return coordinator;
66+
}
67+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.management.rollingupgrade;
19+
20+
import org.apache.ignite.IgniteCheckedException;
21+
import org.apache.ignite.IgniteException;
22+
import org.apache.ignite.internal.management.api.NoArg;
23+
import org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeProcessor;
24+
import org.apache.ignite.internal.processors.task.GridInternal;
25+
import org.apache.ignite.internal.util.lang.IgnitePair;
26+
import org.apache.ignite.internal.visor.VisorJob;
27+
import org.apache.ignite.internal.visor.VisorOneNodeTask;
28+
import org.apache.ignite.lang.IgniteProductVersion;
29+
30+
import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER;
31+
32+
/** Task to disable rolling upgrade. */
33+
@GridInternal
34+
public class RollingUpgradeDisableTask extends VisorOneNodeTask<NoArg, RollingUpgradeTaskResult> {
35+
/** */
36+
private static final long serialVersionUID = 0L;
37+
38+
/** {@inheritDoc} */
39+
@Override protected VisorJob<NoArg, RollingUpgradeTaskResult> job(NoArg arg) {
40+
return new RollingUpgradeDisableJob(arg, debug);
41+
}
42+
43+
/** */
44+
private static class RollingUpgradeDisableJob extends VisorJob<NoArg, RollingUpgradeTaskResult> {
45+
/** */
46+
private static final long serialVersionUID = 0L;
47+
48+
/** */
49+
protected RollingUpgradeDisableJob(NoArg arg, boolean debug) {
50+
super(arg, debug);
51+
}
52+
53+
/** {@inheritDoc} */
54+
@Override protected RollingUpgradeTaskResult run(NoArg arg) throws IgniteException {
55+
RollingUpgradeProcessor proc = ignite.context().rollingUpgrade();
56+
57+
try {
58+
proc.disable();
59+
60+
String buildVer = ignite.localNode().attribute(ATTR_BUILD_VER);
61+
62+
return new RollingUpgradeTaskResult(IgniteProductVersion.fromString(buildVer), null, null);
63+
}
64+
catch (IgniteCheckedException e) {
65+
IgnitePair<IgniteProductVersion> rollUpVers = proc.versions();
66+
67+
return new RollingUpgradeTaskResult(
68+
rollUpVers == null ? null : rollUpVers.get1(),
69+
rollUpVers == null ? null : rollUpVers.get2(),
70+
e.getMessage()
71+
);
72+
}
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)