| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hadoop.yarn.client.cli; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.io.UnsupportedEncodingException; |
| import java.nio.charset.Charset; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.commons.cli.CommandLine; |
| import org.apache.commons.cli.GnuParser; |
| import org.apache.commons.cli.HelpFormatter; |
| import org.apache.commons.cli.MissingArgumentException; |
| import org.apache.commons.cli.Options; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.hadoop.classification.InterfaceAudience.Private; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.util.ToolRunner; |
| import org.apache.hadoop.yarn.api.records.NodeLabel; |
| import org.apache.hadoop.yarn.conf.YarnConfiguration; |
| import org.apache.hadoop.yarn.exceptions.YarnException; |
| import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; |
| |
| import com.google.common.annotations.VisibleForTesting; |
| |
| /** |
| * Cluster CLI used to get over all information of the cluster |
| */ |
| @Private |
| public class ClusterCLI extends YarnCLI { |
| private static final String TITLE = "yarn cluster"; |
| public static final String LIST_LABELS_CMD = "list-node-labels"; |
| public static final String DIRECTLY_ACCESS_NODE_LABEL_STORE = |
| "directly-access-node-label-store"; |
| public static final String CMD = "cluster"; |
| private boolean accessLocal = false; |
| static CommonNodeLabelsManager localNodeLabelsManager = null; |
| |
| public static void main(String[] args) throws Exception { |
| ClusterCLI cli = new ClusterCLI(); |
| cli.setSysOutPrintStream(System.out); |
| cli.setSysErrPrintStream(System.err); |
| int res = ToolRunner.run(cli, args); |
| cli.stop(); |
| System.exit(res); |
| } |
| |
| @Override |
| public int run(String[] args) throws Exception { |
| Options opts = new Options(); |
| |
| opts.addOption("lnl", LIST_LABELS_CMD, false, |
| "List cluster node-label collection"); |
| opts.addOption("h", HELP_CMD, false, "Displays help for all commands."); |
| opts.addOption("dnl", DIRECTLY_ACCESS_NODE_LABEL_STORE, false, |
| "This is DEPRECATED, will be removed in future releases. Directly access node label store, " |
| + "with this option, all node label related operations" |
| + " will NOT connect RM. Instead, they will" |
| + " access/modify stored node labels directly." |
| + " By default, it is false (access via RM)." |
| + " AND PLEASE NOTE: if you configured " |
| + YarnConfiguration.FS_NODE_LABELS_STORE_ROOT_DIR |
| + " to a local directory" |
| + " (instead of NFS or HDFS), this option will only work" |
| + " when the command run on the machine where RM is running." |
| + " Also, this option is UNSTABLE, could be removed in future" |
| + " releases."); |
| |
| int exitCode = -1; |
| CommandLine parsedCli = null; |
| try { |
| parsedCli = new GnuParser().parse(opts, args); |
| } catch (MissingArgumentException ex) { |
| sysout.println("Missing argument for options"); |
| printUsage(opts); |
| return exitCode; |
| } |
| |
| if (parsedCli.hasOption(DIRECTLY_ACCESS_NODE_LABEL_STORE)) { |
| accessLocal = true; |
| } |
| |
| if (parsedCli.hasOption(LIST_LABELS_CMD)) { |
| printClusterNodeLabels(); |
| } else if (parsedCli.hasOption(HELP_CMD)) { |
| printUsage(opts); |
| return 0; |
| } else { |
| syserr.println("Invalid Command Usage : "); |
| printUsage(opts); |
| } |
| return 0; |
| } |
| |
| void printClusterNodeLabels() throws YarnException, IOException { |
| List<NodeLabel> nodeLabels = null; |
| if (accessLocal) { |
| nodeLabels = |
| new ArrayList<>(getNodeLabelManagerInstance(getConf()).getClusterNodeLabels()); |
| } else { |
| nodeLabels = new ArrayList<>(client.getClusterNodeLabels()); |
| } |
| sysout.println(String.format("Node Labels: %s", |
| StringUtils.join(nodeLabels.iterator(), ","))); |
| } |
| |
| @VisibleForTesting |
| static synchronized CommonNodeLabelsManager |
| getNodeLabelManagerInstance(Configuration conf) { |
| if (localNodeLabelsManager == null) { |
| localNodeLabelsManager = new CommonNodeLabelsManager(); |
| localNodeLabelsManager.init(conf); |
| localNodeLabelsManager.start(); |
| } |
| return localNodeLabelsManager; |
| } |
| |
| @VisibleForTesting |
| void printUsage(Options opts) throws UnsupportedEncodingException { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| PrintWriter pw = |
| new PrintWriter(new OutputStreamWriter(baos, Charset.forName("UTF-8"))); |
| new HelpFormatter().printHelp(pw, HelpFormatter.DEFAULT_WIDTH, TITLE, null, |
| opts, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, |
| null); |
| pw.close(); |
| sysout.println(baos.toString("UTF-8")); |
| } |
| } |