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 java.io.PrintStream;
021import java.util.Arrays;
022import java.util.Collection;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.hadoop.fs.CommonConfigurationKeys;
028import org.apache.hadoop.ha.HAAdmin;
029import org.apache.hadoop.ha.HAServiceTarget;
030import org.apache.hadoop.hdfs.DFSConfigKeys;
031import org.apache.hadoop.hdfs.DFSUtil;
032import org.apache.hadoop.hdfs.DFSUtilClient;
033import org.apache.hadoop.hdfs.HdfsConfiguration;
034import org.apache.hadoop.util.ToolRunner;
035
036/**
037 * Class to extend HAAdmin to do a little bit of HDFS-specific configuration.
038 */
039public class DFSHAAdmin extends HAAdmin {
040
041  private static final Log LOG = LogFactory.getLog(DFSHAAdmin.class);
042
043  private String nameserviceId;
044
045  protected void setErrOut(PrintStream errOut) {
046    this.errOut = errOut;
047  }
048  
049  protected void setOut(PrintStream out) {
050    this.out = out;
051  }
052
053  @Override
054  public void setConf(Configuration conf) {
055    if (conf != null) {
056      conf = addSecurityConfiguration(conf);
057    }
058    super.setConf(conf);
059  }
060
061  /**
062   * Add the requisite security principal settings to the given Configuration,
063   * returning a copy.
064   * @param conf the original config
065   * @return a copy with the security settings added
066   */
067  public static Configuration addSecurityConfiguration(Configuration conf) {
068    // Make a copy so we don't mutate it. Also use an HdfsConfiguration to
069    // force loading of hdfs-site.xml.
070    conf = new HdfsConfiguration(conf);
071    String nameNodePrincipal = conf.get(
072        DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "");
073    if (LOG.isDebugEnabled()) {
074      LOG.debug("Using NN principal: " + nameNodePrincipal);
075    }
076
077    conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY,
078        nameNodePrincipal);
079    return conf;
080  }
081
082  /**
083   * Try to map the given namenode ID to its service address.
084   */
085  @Override
086  protected HAServiceTarget resolveTarget(String nnId) {
087    HdfsConfiguration conf = (HdfsConfiguration)getConf();
088    return new NNHAServiceTarget(conf, nameserviceId, nnId);
089  }
090
091  @Override
092  protected String getUsageString() {
093    return "Usage: haadmin [-ns <nameserviceId>]";
094  }
095
096  @Override
097  protected int runCmd(String[] argv) throws Exception {
098    if (argv.length < 1) {
099      printUsage(errOut);
100      return -1;
101    }
102
103    int i = 0;
104    String cmd = argv[i++];
105
106    if ("-ns".equals(cmd)) {
107      if (i == argv.length) {
108        errOut.println("Missing nameservice ID");
109        printUsage(errOut);
110        return -1;
111      }
112      nameserviceId = argv[i++];
113      if (i >= argv.length) {
114        errOut.println("Missing command");
115        printUsage(errOut);
116        return -1;
117      }
118      argv = Arrays.copyOfRange(argv, i, argv.length);
119    }
120
121    return super.runCmd(argv);
122  }
123  
124  /**
125   * returns the list of all namenode ids for the given configuration 
126   */
127  @Override
128  protected Collection<String> getTargetIds(String namenodeToActivate) {
129    return DFSUtilClient.getNameNodeIds(getConf(),
130                                        (nameserviceId != null) ? nameserviceId : DFSUtil.getNamenodeNameServiceId(
131                                            getConf()));
132  }
133  
134  public static void main(String[] argv) throws Exception {
135    int res = ToolRunner.run(new DFSHAAdmin(), argv);
136    System.exit(res);
137  }
138}