001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hdfs.tools; 019 020import com.google.common.base.Preconditions; 021import org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.fs.FileSystem; 023import org.apache.hadoop.hdfs.DFSUtil; 024import org.apache.hadoop.hdfs.DistributedFileSystem; 025import org.apache.hadoop.hdfs.protocol.CachePoolInfo; 026import org.apache.hadoop.tools.TableListing; 027 028import java.io.IOException; 029import java.util.List; 030 031/** 032 * Helper methods for CacheAdmin/CryptoAdmin/StoragePolicyAdmin 033 */ 034public class AdminHelper { 035 /** 036 * Maximum length for printed lines 037 */ 038 static final int MAX_LINE_WIDTH = 80; 039 static final String HELP_COMMAND_NAME = "-help"; 040 041 static DistributedFileSystem getDFS(Configuration conf) 042 throws IOException { 043 FileSystem fs = FileSystem.get(conf); 044 if (!(fs instanceof DistributedFileSystem)) { 045 throw new IllegalArgumentException("FileSystem " + fs.getUri() + 046 " is not an HDFS file system"); 047 } 048 return (DistributedFileSystem)fs; 049 } 050 051 /** 052 * NN exceptions contain the stack trace as part of the exception message. 053 * When it's a known error, pretty-print the error and squish the stack trace. 054 */ 055 static String prettifyException(Exception e) { 056 return e.getClass().getSimpleName() + ": " 057 + e.getLocalizedMessage().split("\n")[0]; 058 } 059 060 static TableListing getOptionDescriptionListing() { 061 return new TableListing.Builder() 062 .addField("").addField("", true) 063 .wrapWidth(MAX_LINE_WIDTH).hideHeaders().build(); 064 } 065 066 /** 067 * Parses a time-to-live value from a string 068 * @return The ttl in milliseconds 069 * @throws IOException if it could not be parsed 070 */ 071 static Long parseTtlString(String maxTtlString) throws IOException { 072 Long maxTtl = null; 073 if (maxTtlString != null) { 074 if (maxTtlString.equalsIgnoreCase("never")) { 075 maxTtl = CachePoolInfo.RELATIVE_EXPIRY_NEVER; 076 } else { 077 maxTtl = DFSUtil.parseRelativeTime(maxTtlString); 078 } 079 } 080 return maxTtl; 081 } 082 083 static Long parseLimitString(String limitString) { 084 Long limit = null; 085 if (limitString != null) { 086 if (limitString.equalsIgnoreCase("unlimited")) { 087 limit = CachePoolInfo.LIMIT_UNLIMITED; 088 } else { 089 limit = Long.parseLong(limitString); 090 } 091 } 092 return limit; 093 } 094 095 static Command determineCommand(String commandName, Command[] commands) { 096 Preconditions.checkNotNull(commands); 097 if (HELP_COMMAND_NAME.equals(commandName)) { 098 return new HelpCommand(commands); 099 } 100 for (Command command : commands) { 101 if (command.getName().equals(commandName)) { 102 return command; 103 } 104 } 105 return null; 106 } 107 108 static void printUsage(boolean longUsage, String toolName, 109 Command[] commands) { 110 Preconditions.checkNotNull(commands); 111 System.err.println("Usage: bin/hdfs " + toolName + " [COMMAND]"); 112 final HelpCommand helpCommand = new HelpCommand(commands); 113 for (AdminHelper.Command command : commands) { 114 if (longUsage) { 115 System.err.print(command.getLongUsage()); 116 } else { 117 System.err.print(" " + command.getShortUsage()); 118 } 119 } 120 System.err.print(longUsage ? helpCommand.getLongUsage() : 121 (" " + helpCommand.getShortUsage())); 122 System.err.println(); 123 } 124 125 interface Command { 126 String getName(); 127 String getShortUsage(); 128 String getLongUsage(); 129 int run(Configuration conf, List<String> args) throws IOException; 130 } 131 132 static class HelpCommand implements Command { 133 private final Command[] commands; 134 135 public HelpCommand(Command[] commands) { 136 Preconditions.checkNotNull(commands != null); 137 this.commands = commands; 138 } 139 140 @Override 141 public String getName() { 142 return HELP_COMMAND_NAME; 143 } 144 145 @Override 146 public String getShortUsage() { 147 return "[-help <command-name>]\n"; 148 } 149 150 @Override 151 public String getLongUsage() { 152 final TableListing listing = AdminHelper.getOptionDescriptionListing(); 153 listing.addRow("<command-name>", "The command for which to get " + 154 "detailed help. If no command is specified, print detailed help for " + 155 "all commands"); 156 return getShortUsage() + "\n" + 157 "Get detailed help about a command.\n\n" + 158 listing.toString(); 159 } 160 161 @Override 162 public int run(Configuration conf, List<String> args) throws IOException { 163 if (args.size() == 0) { 164 for (AdminHelper.Command command : commands) { 165 System.err.println(command.getLongUsage()); 166 } 167 return 0; 168 } 169 if (args.size() != 1) { 170 System.out.println("You must give exactly one argument to -help."); 171 return 0; 172 } 173 final String commandName = args.get(0); 174 // prepend a dash to match against the command names 175 final AdminHelper.Command command = AdminHelper 176 .determineCommand("-" + commandName, commands); 177 if (command == null) { 178 System.err.print("Unknown command '" + commandName + "'.\n"); 179 System.err.print("Valid help command names are:\n"); 180 String separator = ""; 181 for (AdminHelper.Command c : commands) { 182 System.err.print(separator + c.getName().substring(1)); 183 separator = ", "; 184 } 185 System.err.print("\n"); 186 return 1; 187 } 188 System.err.print(command.getLongUsage()); 189 return 0; 190 } 191 } 192}