errose28 commented on code in PR #7944:
URL: https://github.com/apache/ozone/pull/7944#discussion_r1970839829
##########
hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/container/ReconcileSubcommand.java:
##########
@@ -34,15 +48,188 @@
versionProvider = HddsVersionProvider.class)
public class ReconcileSubcommand extends ScmSubcommand {
- @CommandLine.Parameters(description = "ID of the container to reconcile")
- private long containerId;
+ @CommandLine.Parameters(description = "One or more container IDs separated
by spaces. " +
+ "To read from stdin, specify '-' and supply the container IDs " +
+ "separated by newlines.",
+ arity = "1..*",
+ paramLabel = "<container ID>")
+ private List<String> containerList;
+
+ @CommandLine.Option(names = { "--status" },
+ defaultValue = "false",
+ fallbackValue = "true",
+ description = "Display the reconciliation status of this container's
replicas")
+ private boolean status;
@Override
public void execute(ScmClient scmClient) throws IOException {
- scmClient.reconcileContainer(containerId);
- System.out.println("Reconciliation has been triggered for container " +
containerId);
- // TODO a better option to check status may be added later.
- System.out.println("Use \"ozone admin container info --json " +
containerId + "\" to see the checksums of each " +
- "container replica");
+ Iterator<String> idIterator;
+ // PicoCLI arity check guarantees at least one element will be present.
+ if (containerList.get(0).equals("-")) {
+ // Read from stdin.
+ idIterator = new Scanner(System.in, StandardCharsets.UTF_8.name());
+ } else {
+ // A list of containers was provided.
+ idIterator = containerList.iterator();
+ }
+
+ if (status) {
+ // Automatically creates one array for the output, while allowing us to
flush each object individually.
+ try (SequenceWriter arrayWriter =
JsonUtils.getSequenceWriter(System.out)) {
+ // Since status is retrieved using container info, do client side
validation that it is only used for Ratis
+ // containers. If EC containers are given, print a message to stderr
and eventually exit non-zero, but continue
+ // processing the remaining containers.
+ int invalidCount = 0;
+ while (idIterator.hasNext()) {
+ long containerID = Long.parseLong(idIterator.next());
+ if (!printReconciliationStatus(scmClient, containerID, arrayWriter))
{
+ invalidCount++;
+ }
+ }
+ if (invalidCount > 0) {
+ throw new RuntimeException("Failed to process reconciliation status
for " + invalidCount + " containers");
+ }
+ }
+ } else {
+ int invalidCount = 0;
+ while (idIterator.hasNext()) {
+ long containerID = Long.parseLong(idIterator.next());
+ try {
+ executeReconciliation(scmClient, containerID);
+ } catch (Exception ex) {
+ System.err.println("Failed to send reconciliation to container " +
containerID + ": " + ex.getMessage());
+ invalidCount++;
+ }
+ }
+ if (invalidCount > 0) {
+ throw new RuntimeException("Failed trigger reconciliation for " +
invalidCount + " containers");
+ }
+ }
+ }
+
+ private boolean printReconciliationStatus(ScmClient scmClient, long
containerID, SequenceWriter arrayWriter)
+ throws IOException {
+ ContainerInfo containerInfo = scmClient.getContainer(containerID);
+ if (containerInfo.getReplicationType() !=
HddsProtos.ReplicationType.RATIS) {
+ System.err.println("Cannot get status of container " + containerID +
+ ". Reconciliation is only supported for Ratis replicated
containers");
+ return false;
+ }
+ List<ContainerReplicaInfo> replicas =
scmClient.getContainerReplicas(containerID);
+ arrayWriter.write(new ContainerWrapper(containerInfo, replicas));
+ arrayWriter.flush();
+ return true;
+ }
+
+ private void executeReconciliation(ScmClient scmClient, long containerID)
throws IOException {
+ scmClient.reconcileContainer(containerID);
+ System.out.println("Reconciliation has been triggered for container " +
containerID);
+ System.out.println("Use \"ozone admin container reconcile --status " +
containerID + "\" to see the checksums of " +
+ "each container replica");
Review Comment:
Agreed, some sort of feedback that it finished would be good. I was planning
to revisit this with the SCM integration. For example, SCM may end up tracking
the known in-flight reconciliations and could report the results.
Are you suggesting adding a jmx metric or just a counter in the code? I'm
not sure exactly how this work, but I imagine the counter would get persisted
on the DN side and SCM would see the updates. Users would then look for the
count to increase when they send in a command.
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]