/** * 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.Collections; import java.util.List; import java.util.Set; 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.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, "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; } private List<String> sortStrSet(Set<String> labels) { List<String> list = new ArrayList<String>(); list.addAll(labels); Collections.sort(list); return list; } void printClusterNodeLabels() throws YarnException, IOException { Set<String> nodeLabels = null; if (accessLocal) { nodeLabels = getNodeLabelManagerInstance(getConf()).getClusterNodeLabels(); } else { nodeLabels = client.getClusterNodeLabels(); } sysout.println(String.format("Node Labels: %s", StringUtils.join(sortStrSet(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")); } }