Skip to content

Commit 3304467

Browse files
committed
YARN-11593. [Federation] Improve command line help information.
1 parent 2736f88 commit 3304467

File tree

1 file changed

+149
-70
lines changed
  • hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli

1 file changed

+149
-70
lines changed

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/RouterCLI.java

Lines changed: 149 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.apache.commons.cli.Option;
2424
import org.apache.commons.cli.Options;
2525
import org.apache.commons.cli.ParseException;
26+
import org.apache.commons.collections.CollectionUtils;
27+
import org.apache.commons.collections.MapUtils;
2628
import org.apache.commons.lang3.StringUtils;
2729
import org.apache.hadoop.conf.Configuration;
2830
import org.apache.hadoop.conf.Configured;
@@ -63,10 +65,7 @@
6365
import java.io.PrintWriter;
6466
import java.nio.charset.Charset;
6567
import java.nio.charset.StandardCharsets;
66-
import java.util.Arrays;
67-
import java.util.ArrayList;
68-
import java.util.List;
69-
import java.util.Map;
68+
import java.util.*;
7069
import java.util.stream.Collectors;
7170

7271
import static org.apache.hadoop.yarn.server.api.protocolrecords.FederationQueueWeight.checkHeadRoomAlphaValid;
@@ -77,25 +76,75 @@ public class RouterCLI extends Configured implements Tool {
7776

7877
private static final Logger LOG = LoggerFactory.getLogger(RouterCLI.class);
7978

80-
protected final static Map<String, UsageInfo> ADMIN_USAGE =
81-
ImmutableMap.<String, UsageInfo>builder()
82-
// Command1: deregisterSubCluster
83-
.put("-deregisterSubCluster", new UsageInfo(
84-
"[-sc|--subClusterId [subCluster Id]]",
85-
"Deregister SubCluster, If the interval between the heartbeat time of the subCluster " +
86-
"and the current time exceeds the timeout period, " +
87-
"set the state of the subCluster to SC_LOST."))
88-
// Command2: policy
89-
.put("-policy", new UsageInfo(
90-
"[-s|--save [queue;router weight;amrm weight;headroomalpha]] " +
91-
"[-bs|--batch-save [--format xml] [-f|--input-file fileName]]" +
92-
"[-l|--list [--pageSize][--currentPage][--queue][--queues]]",
93-
"We provide a set of commands for Policy:" +
94-
" Include list policies, save policies, batch save policies. " +
95-
" (Note: The policy type will be directly read from the" +
96-
" yarn.federation.policy-manager in the local yarn-site.xml.)" +
97-
" eg. (routeradmin -policy [-s|--save] root.a;SC-1:0.7,SC-2:0.3;SC-1:0.7,SC-2:0.3;1.0)"))
98-
.build();
79+
protected final static UsageInfo subClusterId = new UsageInfo("<-sc|--subClusterId>",
80+
"'-sc' option allows you to specify the sub-cluster to operate on, " +
81+
"while the '--subClusterId' option is the long format of -sc and serves the same purpose.");
82+
protected final static String dsExample_1 = "yarn routeradmin -deregisterSubCluster -sc SC-1";
83+
protected final static String dsExample_2 = "yarn routeradmin -deregisterSubCluster --subClusterId SC-1";
84+
85+
protected final static RouterExampleUsageInfos dsExampleUsageInfos_1 = new RouterExampleUsageInfos(
86+
Arrays.asList(dsExample_1, dsExample_2),
87+
Arrays.asList("At this point we can use the following command:"));
88+
protected final static RouterUsageInfos deregisterSubCluster =
89+
new RouterUsageInfos(Arrays.asList(subClusterId),
90+
Arrays.asList("deregister subCluster, If the interval between the heartbeat time of the subCluster" +
91+
"and the current time exceeds the timeout period, set the state of the subCluster to SC_LOST."),
92+
ImmutableMap.<String, RouterExampleUsageInfos>builder()
93+
.put("<--deregisterSubCluster>", dsExampleUsageInfos_1)
94+
.build());
95+
96+
protected final static UsageInfo policySaveUsage = new UsageInfo(
97+
"<-s|--save [queue;router weight;amrm weight;headroomalpha]>",
98+
"We will save the policy information of the queue, including queue and weight information.");
99+
protected final static UsageInfo policyBatchSaveUsage = new UsageInfo(
100+
"<-bs|--batch-save [--format xml] [-f|--input-file fileName]]>",
101+
"We will save queue policies in bulk, where users can provide XML files containing the policies.");
102+
protected final static UsageInfo policyListUsage = new UsageInfo("<-l|--list [--pageSize][--currentPage][--queue][--queues]>",
103+
"We can display the configured queue policies.");
104+
105+
protected final static String pExample_1 = "yarn routeradmin -policy -s root.a;SC-1:0.7,SC-2:0.3;SC-1:0.6,SC-2:0.4;1.0";
106+
protected final static String pExample_2 = "yarn routeradmin -policy --save root.a;SC-1:0.7,SC-2:0.3;SC-1:0.6,SC-2:0.4;1.0";
107+
protected final static RouterExampleUsageInfos pExampleUsageInfos_1 = new RouterExampleUsageInfos(
108+
Arrays.asList(pExample_1, pExample_2),
109+
Arrays.asList("We have two subClusters, SC-1 and SC-2. For queue root.a, we want the ratio to be set to SC-1:SC-2=0.7:0.3 when routing.",
110+
"Additionally, when AM applies containers, we want the allocation ratio to be SC-1:SC-2=0.6:0.4.",
111+
"Headroomalpha can be set to the default value of 1.0.",
112+
"At this point we can use the following command:"));
113+
114+
protected final static String pExample_3 = "yarn routeradmin -policy -bs --format xml -f queue.xml";
115+
protected final static String pExample_4 = "yarn routeradmin -policy --batch-save --format xml -f queue.xml";
116+
protected final static RouterExampleUsageInfos pExampleUsageInfos_2 = new RouterExampleUsageInfos(
117+
Arrays.asList(pExample_3, pExample_4),
118+
Arrays.asList("We offer the capability to batch input queue policies. ",
119+
"Currently, this is supported exclusively through XML. " +
120+
"(We can find federationWeights.xml in the Federation.md on the website.) ",
121+
"We can use the batch-save command to input proportion information. ",
122+
"At this point we can use the following command:"));
123+
124+
protected final static String pExample_5 = "yarn routeradmin -policy -l --pageSize 20 --currentPage 1 --queue root.a";
125+
protected final static String pExample_6 = "yarn routeradmin -policy -list --pageSize 20 --currentPage 1 --queues root.a,root.b";
126+
protected final static RouterExampleUsageInfos pExampleUsageInfos_3 = new RouterExampleUsageInfos(
127+
Arrays.asList(pExample_5, pExample_6),
128+
Arrays.asList("We can print the Configured Queue Policies on the command line. ",
129+
"We can specify a queue through --queue, and we can specify a queue list through --queues.",
130+
"At this point we can use the following command:"));
131+
132+
protected final static RouterUsageInfos policy =
133+
new RouterUsageInfos(Arrays.asList(policySaveUsage, policyBatchSaveUsage, policyListUsage),
134+
Arrays.asList("We provide a set of commands for Policy Include list policies, save policies, batch save policies."),
135+
ImmutableMap.<String, RouterExampleUsageInfos>builder()
136+
.put("<-s|--save>", pExampleUsageInfos_1)
137+
.put("<-bs|--batch-save>", pExampleUsageInfos_2)
138+
.put("<-l|--list>", pExampleUsageInfos_3)
139+
.build());
140+
141+
protected final static Map<String, RouterUsageInfos> ADMIN_USAGE =
142+
ImmutableMap.<String, RouterUsageInfos>builder()
143+
// Command1: deregisterSubCluster
144+
.put("-deregisterSubCluster", deregisterSubCluster)
145+
// Command2: policy
146+
.put("-policy", policy)
147+
.build();
99148

100149
// Common Constant
101150
private static final String SEMICOLON = ";";
@@ -135,7 +184,7 @@ public class RouterCLI extends Configured implements Tool {
135184

136185
private static final String CMD_POLICY = "-policy";
137186
private static final String FORMAT_XML = "xml";
138-
private static final String FORMAT_JSON = "json";
187+
139188
private static final String XML_TAG_SUBCLUSTERIDINFO = "subClusterIdInfo";
140189
private static final String XML_TAG_AMRMPOLICYWEIGHTS = "amrmPolicyWeights";
141190
private static final String XML_TAG_ROUTERPOLICYWEIGHTS = "routerPolicyWeights";
@@ -159,43 +208,59 @@ public RouterCLI(Configuration conf) {
159208
}
160209

161210
private static void buildHelpMsg(String cmd, StringBuilder builder) {
162-
UsageInfo usageInfo = ADMIN_USAGE.get(cmd);
163-
if (usageInfo == null) {
211+
RouterUsageInfos routerUsageInfo = ADMIN_USAGE.get(cmd);
212+
213+
if (routerUsageInfo == null) {
164214
return;
165215
}
216+
builder.append("[" + cmd + "]\n");
166217

167-
if (usageInfo.args != null) {
168-
String space = (usageInfo.args == "") ? "" : " ";
169-
builder.append(" ")
170-
.append(cmd)
171-
.append(space)
172-
.append(usageInfo.args)
173-
.append(": ")
174-
.append(usageInfo.help);
175-
} else {
176-
builder.append(" ")
177-
.append(cmd)
178-
.append(": ")
179-
.append(usageInfo.help);
218+
if (!routerUsageInfo.helpInfos.isEmpty()) {
219+
builder.append("\t Description: \n");
220+
for (String helpInfo : routerUsageInfo.helpInfos) {
221+
builder.append("\t\t" + helpInfo).append("\n\n");
222+
}
180223
}
181-
}
182224

183-
private static void buildIndividualUsageMsg(String cmd, StringBuilder builder) {
184-
UsageInfo usageInfo = ADMIN_USAGE.get(cmd);
185-
if (usageInfo == null) {
186-
return;
225+
if (!routerUsageInfo.usageInfos.isEmpty()) {
226+
builder.append("\t UsageInfos: \n");
227+
for (UsageInfo usageInfo : routerUsageInfo.usageInfos) {
228+
builder.append("\t\t"+usageInfo.args)
229+
.append(": ")
230+
.append("\n\t\t")
231+
.append(usageInfo.help).append("\n\n");
232+
}
187233
}
188-
if (usageInfo.args == null) {
189-
builder.append("Usage: routeradmin [")
190-
.append(cmd)
191-
.append("]\n");
192-
} else {
193-
String space = (usageInfo.args == "") ? "" : " ";
194-
builder.append("Usage: routeradmin [")
195-
.append(cmd)
196-
.append(space)
197-
.append(usageInfo.args)
198-
.append("]\n");
234+
235+
if (MapUtils.isNotEmpty(routerUsageInfo.examples)) {
236+
builder.append("\t Examples: \n");
237+
int count = 1;
238+
for (Map.Entry<String, RouterExampleUsageInfos> example :
239+
routerUsageInfo.examples.entrySet()) {
240+
String key = example.getKey();
241+
builder.append("\t\t").append("Cmd:" + count + ". ").append(key).append(": \n\n");
242+
RouterExampleUsageInfos values = example.getValue();
243+
if (values == null) {
244+
return;
245+
}
246+
// Print Command Description
247+
if (CollectionUtils.isNotEmpty(values.desc)) {
248+
builder.append("\t\t").append("Cmd Requirement Description:\n");
249+
for (String value : values.desc) {
250+
builder.append("\t\t").append(value).append("\n");
251+
}
252+
}
253+
builder.append("\n");
254+
// Print Command example
255+
if (CollectionUtils.isNotEmpty(values.examples)) {
256+
builder.append("\t\t").append("Cmd Examples:\n");
257+
for (String value : values.examples) {
258+
builder.append("\t\t").append(value).append("\n");
259+
}
260+
}
261+
builder.append("\n");
262+
count++;
263+
}
199264
}
200265
}
201266

@@ -204,12 +269,7 @@ private static void printHelp() {
204269
summary.append("routeradmin is the command to execute ")
205270
.append("YARN Federation administrative commands.\n")
206271
.append("The full syntax is: \n\n")
207-
.append("routeradmin\n")
208-
.append(" [-deregisterSubCluster [-sc|--subClusterId [subCluster Id]]\n")
209-
.append(" [-policy [-s|--save [queue;router weight;amrm weight;headroomalpha] " +
210-
"[-bs|--batch-save [--format xml,json] [-f|--input-file fileName]]] " +
211-
"[-l|--list [--pageSize][--currentPage][--queue][--queues]]\n")
212-
.append(" [-help [cmd]]").append("\n");
272+
.append("routeradmin\n");
213273
StringBuilder helpBuilder = new StringBuilder();
214274
System.out.println(summary);
215275

@@ -235,21 +295,17 @@ protected ResourceManagerAdministrationProtocol createAdminProtocol()
235295
private static void buildUsageMsg(StringBuilder builder) {
236296
builder.append("routeradmin is only used in Yarn Federation Mode.\n");
237297
builder.append("Usage: routeradmin\n");
238-
for (Map.Entry<String, UsageInfo> cmdEntry : ADMIN_USAGE.entrySet()) {
239-
UsageInfo usageInfo = cmdEntry.getValue();
240-
builder.append(" ")
241-
.append(cmdEntry.getKey())
242-
.append(" ")
243-
.append(usageInfo.args)
244-
.append("\n");
298+
for (String cmdKey : ADMIN_USAGE.keySet()) {
299+
buildHelpMsg(cmdKey, builder);
300+
builder.append("\n");
245301
}
246302
builder.append(" -help [cmd]\n");
247303
}
248304

249305
private static void printUsage(String cmd) {
250306
StringBuilder usageBuilder = new StringBuilder();
251307
if (ADMIN_USAGE.containsKey(cmd)) {
252-
buildIndividualUsageMsg(cmd, usageBuilder);
308+
buildHelpMsg(cmd, usageBuilder);
253309
} else {
254310
buildUsageMsg(usageBuilder);
255311
}
@@ -353,7 +409,7 @@ private int handlePolicy(String[] args)
353409
saveOpt.setOptionalArg(true);
354410
Option batchSaveOpt = new Option(OPTION_BATCH_S, OPTION_BATCH_SAVE, false,
355411
"We will save queue policies in bulk, " +
356-
"where users can provide XML or JSON files containing the policies. " +
412+
"where users can provide XML files containing the policies. " +
357413
"This command will parse the file contents and store the results " +
358414
"in the FederationStateStore.");
359415
Option formatOpt = new Option(null, "format", true,
@@ -748,6 +804,29 @@ public int run(String[] args) throws Exception {
748804
return EXIT_SUCCESS;
749805
}
750806

807+
private static class RouterExampleUsageInfos {
808+
public List<String> examples;
809+
public List<String> desc;
810+
811+
public RouterExampleUsageInfos(List<String> examples, List<String> desc) {
812+
this.examples = examples;
813+
this.desc = desc;
814+
}
815+
}
816+
817+
private static class RouterUsageInfos {
818+
public List<UsageInfo> usageInfos;
819+
public List<String> helpInfos;
820+
public Map<String, RouterExampleUsageInfos> examples;
821+
822+
public RouterUsageInfos(List<UsageInfo> usageInfos, List<String> helpInfos,
823+
Map<String, RouterExampleUsageInfos> examples) {
824+
this.usageInfos = usageInfos;
825+
this.helpInfos = helpInfos;
826+
this.examples = examples;
827+
}
828+
}
829+
751830
public static void main(String[] args) throws Exception {
752831
int result = ToolRunner.run(new RouterCLI(), args);
753832
System.exit(result);

0 commit comments

Comments
 (0)