Skip to content

HDDS-15715. Add helpful CLI flags to finalization CLIs#10678

Open
dombizita wants to merge 3 commits into
apache:HDDS-14496-zdufrom
dombizita:HDDS-15715
Open

HDDS-15715. Add helpful CLI flags to finalization CLIs#10678
dombizita wants to merge 3 commits into
apache:HDDS-14496-zdufrom
dombizita:HDDS-15715

Conversation

@dombizita

@dombizita dombizita commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Added new CLI flags to the upgrade finalization CLI:

  • finalize --wait: the client will periodically poll the cluster for status from OM until the whole cluster is finalized. The finalize command is idempotent so waiting can be resumed at any time
  • status --json: json version of the status output for scripting
  • status --verbose: includes internal information like OM and SCM software and apparent versions, the min and max DN software and apparent versions in the cluster

Used Claude Opus 4.8 for planning and coding, reviewed by me.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-15715

How was this patch tested?

Added unit tests, green run on my fork: https://github.com/dombizita/ozone/actions/runs/28660447709

@github-actions github-actions Bot added the zdu Pull requests for Zero Downtime Upgrade (ZDU) https://issues.apache.org/jira/browse/HDDS-14496 label Jul 6, 2026
@errose28 errose28 self-requested a review July 7, 2026 18:42

@errose28 errose28 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this @dombizita.

optional int32 numDatanodesFinalized = 2;
optional int32 numDatanodesTotal = 3;
optional bool shouldFinalize = 4;
optional uint32 scmSoftwareVersion = 5;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will only be the leader SCM's software version. Unlike apparent version, these may not always match between SCMs. Maybe we should only return apparent versions of all components with the verbose option, not software version?

Note that software version can also be misleading if there was no component version change across an upgrade. In that case all versions can match even if the cluster is in mixed versions.

return numFinalizedDatanodes == totalHealthyDatanodes;
}

public Integer getMinApparentVersion() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Integer object instead of int primitive for these getters?

Comment on lines +186 to +191
if (dnApparentVersionInt < minApparentVersion) {
minApparentVersion = dnApparentVersionInt;
}
if (dnApparentVersionInt > maxApparentVersion) {
maxApparentVersion = dnApparentVersionInt;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit.

Suggested change
if (dnApparentVersionInt < minApparentVersion) {
minApparentVersion = dnApparentVersionInt;
}
if (dnApparentVersionInt > maxApparentVersion) {
maxApparentVersion = dnApparentVersionInt;
}
minApparentVersion = Math.min(minApparentVersion, dnApparentVersionInt);
maxApparentVersion = Math.max(maxApparentVersion, dnApparentVersionInt);

Comment on lines +207 to +208
return new DatanodeFinalizationCounts(finalizedNodes, totalHealthyNodes,
minApparentVersion, maxApparentVersion);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional, but might be better to make this a builder so all the int parameters don't accidentally get swapped.

out.println(" SCM Apparent Version: " + formatHddsVersion(hdds.hasScmApparentVersion(),
hdds.getScmApparentVersion()));
out.println(" Datanodes finalized: " + hdds.getNumDatanodesFinalized() + "/" + hdds.getNumDatanodesTotal());
out.println(" Min DN Apparent Version: " + formatHddsVersion(hdds.hasMinDatanodeApparentVersion(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
out.println(" Min DN Apparent Version: " + formatHddsVersion(hdds.hasMinDatanodeApparentVersion(),
out.println(" Min Datanode Apparent Version: " + formatHddsVersion(hdds.hasMinDatanodeApparentVersion(),

}

@Override
public HddsProtos.UpgradeStatus queryUpgradeStatus() throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should block this query when SCM is in safemode just like the finalize command. This way we don't have to handle the zero datanode case.

}

@Test
public void testWaitFlagCompletesImmediatelyWhenAlreadyFinalized() throws Exception {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test does not actually check that the poll interval is not used when the cluster is already finalized. In the current version the wait flag actually doesn't complete immediately when the cluster is already finalized: it still waits 5 seconds.

Suggested change
public void testWaitFlagCompletesImmediatelyWhenAlreadyFinalized() throws Exception {
public void testStatusCalledOnceWhenAlreadyFinalized() throws Exception {


String output = outContent.toString(DEFAULT_ENCODING);
assertTrue(output.contains("Waiting interrupted"));
verify(omClient, never()).queryUpgradeStatus();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we remove the initial delay in the polling this should call the query command once.

try {
cmd.call();
} catch (Exception ignored) {
// assertion in main thread

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still make sure this failed with the correct result, either by checking the exception type or the thread's interrupt flag.

assertEquals(0, cmd.call());

String output = outContent.toString(DEFAULT_ENCODING);
// Verbose output uses the StatusSubCommand.printVerbose layout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any checks on verbose specific output here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

zdu Pull requests for Zero Downtime Upgrade (ZDU) https://issues.apache.org/jira/browse/HDDS-14496

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants