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