|
@@ -38,13 +38,24 @@ import org.apache.hadoop.security.ssl.SSLFactory;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
import org.apache.hadoop.util.Tool;
|
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
|
+import org.apache.hadoop.yarn.webapp.dao.ConfInfo;
|
|
|
import org.apache.hadoop.yarn.webapp.dao.QueueConfigInfo;
|
|
|
import org.apache.hadoop.yarn.webapp.dao.SchedConfUpdateInfo;
|
|
|
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
|
|
|
import org.apache.hadoop.yarn.webapp.util.YarnWebServiceUtils;
|
|
|
|
|
|
+import javax.xml.bind.JAXBContext;
|
|
|
+import javax.xml.bind.Marshaller;
|
|
|
+import javax.xml.transform.OutputKeys;
|
|
|
+import javax.xml.transform.Source;
|
|
|
+import javax.xml.transform.Transformer;
|
|
|
+import javax.xml.transform.TransformerFactory;
|
|
|
+import javax.xml.transform.stream.StreamResult;
|
|
|
+import javax.xml.transform.stream.StreamSource;
|
|
|
import javax.ws.rs.core.MediaType;
|
|
|
import javax.ws.rs.core.Response.Status;
|
|
|
+import java.io.StringReader;
|
|
|
+import java.io.StringWriter;
|
|
|
import java.io.IOException;
|
|
|
import java.net.HttpURLConnection;
|
|
|
import java.net.URL;
|
|
@@ -65,12 +76,16 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
private static final String REMOVE_QUEUES_OPTION = "removeQueues";
|
|
|
private static final String UPDATE_QUEUES_OPTION = "updateQueues";
|
|
|
private static final String GLOBAL_OPTIONS = "globalUpdates";
|
|
|
+ private static final String GET_SCHEDULER_CONF = "getConf";
|
|
|
private static final String FORMAT_CONF = "formatConfig";
|
|
|
private static final String HELP_CMD = "help";
|
|
|
|
|
|
private static final String CONF_ERR_MSG = "Specify configuration key " +
|
|
|
"value as confKey=confVal.";
|
|
|
|
|
|
+ private SSLFactory sslFactory;
|
|
|
+ private Client client;
|
|
|
+
|
|
|
public SchedConfCLI() {
|
|
|
super(new YarnConfiguration());
|
|
|
}
|
|
@@ -93,6 +108,8 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
"Update queue configurations");
|
|
|
opts.addOption("global", GLOBAL_OPTIONS, true,
|
|
|
"Update global scheduler configurations");
|
|
|
+ opts.addOption("getconf", GET_SCHEDULER_CONF, false,
|
|
|
+ "Get current scheduler configurations");
|
|
|
opts.addOption("format", FORMAT_CONF, false,
|
|
|
"Format Scheduler Configuration and reload from" +
|
|
|
" capacity-scheduler.xml");
|
|
@@ -115,6 +132,7 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
|
|
|
boolean hasOption = false;
|
|
|
boolean format = false;
|
|
|
+ boolean getConf = false;
|
|
|
SchedConfUpdateInfo updateInfo = new SchedConfUpdateInfo();
|
|
|
try {
|
|
|
if (parsedCli.hasOption(ADD_QUEUES_OPTION)) {
|
|
@@ -139,6 +157,10 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
hasOption = true;
|
|
|
format = true;
|
|
|
}
|
|
|
+ if (parsedCli.hasOption(GET_SCHEDULER_CONF)) {
|
|
|
+ hasOption = true;
|
|
|
+ getConf = true;
|
|
|
+ }
|
|
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
System.err.println(e.getMessage());
|
|
@@ -154,27 +176,98 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
Configuration conf = getConf();
|
|
|
if (format) {
|
|
|
return WebAppUtils.execOnActiveRM(conf, this::formatSchedulerConf, null);
|
|
|
+ } else if (getConf) {
|
|
|
+ return WebAppUtils.execOnActiveRM(conf, this::getSchedulerConf, null);
|
|
|
} else {
|
|
|
return WebAppUtils.execOnActiveRM(conf,
|
|
|
this::updateSchedulerConfOnRMNode, updateInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @VisibleForTesting
|
|
|
- int formatSchedulerConf(String webAppAddress, WebResource resource)
|
|
|
+ private static void prettyFormatWithIndent(String input, int indent)
|
|
|
throws Exception {
|
|
|
+ Source xmlInput = new StreamSource(new StringReader(input));
|
|
|
+ StringWriter sw = new StringWriter();
|
|
|
+ StreamResult xmlOutput = new StreamResult(sw);
|
|
|
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
|
|
+ transformerFactory.setAttribute("indent-number", indent);
|
|
|
+ Transformer transformer = transformerFactory.newTransformer();
|
|
|
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
|
|
+ transformer.transform(xmlInput, xmlOutput);
|
|
|
+ System.out.println(xmlOutput.getWriter().toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ private WebResource initializeWebResource(String webAppAddress) {
|
|
|
Configuration conf = getConf();
|
|
|
- SSLFactory clientSslFactory = null;
|
|
|
if (YarnConfiguration.useHttps(conf)) {
|
|
|
- clientSslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
|
|
|
+ sslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
|
|
|
}
|
|
|
- Client webServiceClient = createWebServiceClient(clientSslFactory);
|
|
|
+ client = createWebServiceClient(sslFactory);
|
|
|
+ return client.resource(webAppAddress);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void destroyClient() {
|
|
|
+ if (client != null) {
|
|
|
+ client.destroy();
|
|
|
+ }
|
|
|
+ if (sslFactory != null) {
|
|
|
+ sslFactory.destroy();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @VisibleForTesting
|
|
|
+ int getSchedulerConf(String webAppAddress, WebResource resource)
|
|
|
+ throws Exception {
|
|
|
ClientResponse response = null;
|
|
|
resource = (resource != null) ? resource :
|
|
|
- webServiceClient.resource(webAppAddress);
|
|
|
+ initializeWebResource(webAppAddress);
|
|
|
+ try {
|
|
|
+ Builder builder;
|
|
|
+ if (UserGroupInformation.isSecurityEnabled()) {
|
|
|
+ builder = resource
|
|
|
+ .path("ws").path("v1").path("cluster")
|
|
|
+ .path("scheduler-conf").accept(MediaType.APPLICATION_XML);
|
|
|
+ } else {
|
|
|
+ builder = resource
|
|
|
+ .path("ws").path("v1").path("cluster").path("scheduler-conf")
|
|
|
+ .queryParam("user.name", UserGroupInformation.getCurrentUser()
|
|
|
+ .getShortUserName()).accept(MediaType.APPLICATION_XML);
|
|
|
+ }
|
|
|
+ response = builder.get(ClientResponse.class);
|
|
|
+ if (response != null) {
|
|
|
+ if (response.getStatus() == Status.OK.getStatusCode()) {
|
|
|
+ ConfInfo schedulerConf = response.getEntity(ConfInfo.class);
|
|
|
+ JAXBContext jaxbContext = JAXBContext.newInstance(ConfInfo.class);
|
|
|
+ Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
|
|
|
+ StringWriter sw = new StringWriter();
|
|
|
+ jaxbMarshaller.marshal(schedulerConf, sw);
|
|
|
+ prettyFormatWithIndent(sw.toString(), 2);
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ System.err.println("Failed to get scheduler configuration: "
|
|
|
+ + response.getEntity(String.class));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ System.err.println("Failed to get scheduler configuration: " +
|
|
|
+ "null response");
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ } finally {
|
|
|
+ if (response != null) {
|
|
|
+ response.close();
|
|
|
+ }
|
|
|
+ destroyClient();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
+ int formatSchedulerConf(String webAppAddress, WebResource resource)
|
|
|
+ throws Exception {
|
|
|
+ ClientResponse response = null;
|
|
|
+ resource = (resource != null) ? resource :
|
|
|
+ initializeWebResource(webAppAddress);
|
|
|
try {
|
|
|
- Builder builder = null;
|
|
|
+ Builder builder;
|
|
|
if (UserGroupInformation.isSecurityEnabled()) {
|
|
|
builder = resource
|
|
|
.path("ws").path("v1").path("cluster")
|
|
@@ -206,27 +299,15 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
if (response != null) {
|
|
|
response.close();
|
|
|
}
|
|
|
- if (webServiceClient != null) {
|
|
|
- webServiceClient.destroy();
|
|
|
- }
|
|
|
- if (clientSslFactory != null) {
|
|
|
- clientSslFactory.destroy();
|
|
|
- }
|
|
|
+ destroyClient();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@VisibleForTesting
|
|
|
int updateSchedulerConfOnRMNode(String webAppAddress,
|
|
|
SchedConfUpdateInfo updateInfo) throws Exception {
|
|
|
- Configuration conf = getConf();
|
|
|
- SSLFactory clientSslFactory = null;
|
|
|
- if (YarnConfiguration.useHttps(conf)) {
|
|
|
- clientSslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
|
|
|
- }
|
|
|
- Client webServiceClient = createWebServiceClient(clientSslFactory);
|
|
|
ClientResponse response = null;
|
|
|
- WebResource resource = webServiceClient.resource(webAppAddress);
|
|
|
-
|
|
|
+ WebResource resource = initializeWebResource(webAppAddress);
|
|
|
try {
|
|
|
Builder builder = null;
|
|
|
if (UserGroupInformation.isSecurityEnabled()) {
|
|
@@ -258,12 +339,7 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
if (response != null) {
|
|
|
response.close();
|
|
|
}
|
|
|
- if (webServiceClient != null) {
|
|
|
- webServiceClient.destroy();
|
|
|
- }
|
|
|
- if (clientSslFactory != null) {
|
|
|
- clientSslFactory.destroy();
|
|
|
- }
|
|
|
+ destroyClient();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -380,7 +456,8 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
+ "[-update \"queueUpdatePath1:confKey1=confVal1\"] "
|
|
|
+ "[-global globalConfKey1=globalConfVal1,"
|
|
|
+ "globalConfKey2=globalConfVal2] "
|
|
|
- + "[-format]\n"
|
|
|
+ + "[-format] "
|
|
|
+ + "[-getconf]\n"
|
|
|
+ "Example (adding queues): yarn schedulerconf -add "
|
|
|
+ "\"root.a.a1:capacity=100,maximum-capacity=100;root.a.a2:capacity=0,"
|
|
|
+ "maximum-capacity=0\"\n"
|
|
@@ -393,6 +470,8 @@ public class SchedConfCLI extends Configured implements Tool {
|
|
|
+ "-global yarn.scheduler.capacity.maximum-applications=10000\n"
|
|
|
+ "Example (format scheduler configuration): yarn schedulerconf "
|
|
|
+ "-format\n"
|
|
|
+ + "Example (get scheduler configuration): yarn schedulerconf "
|
|
|
+ + "-getconf\n"
|
|
|
+ "Note: This is an alpha feature, the syntax/options are subject to "
|
|
|
+ "change, please run at your own risk.");
|
|
|
}
|