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 org.apache.hadoop.conf.Configuration;
021import org.apache.hadoop.conf.Configured;
022import org.apache.hadoop.fs.Path;
023import org.apache.hadoop.hdfs.DistributedFileSystem;
024import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;
025import org.apache.hadoop.hdfs.protocol.HdfsFileStatus;
026import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite;
027import org.apache.hadoop.tools.TableListing;
028import org.apache.hadoop.util.StringUtils;
029import org.apache.hadoop.util.Tool;
030
031import java.io.IOException;
032import java.util.Arrays;
033import java.util.LinkedList;
034import java.util.List;
035
036/**
037 * This class implements block storage policy operations.
038 */
039public class StoragePolicyAdmin extends Configured implements Tool {
040
041  public static void main(String[] argsArray) throws Exception {
042    final StoragePolicyAdmin admin = new StoragePolicyAdmin(new
043        Configuration());
044    System.exit(admin.run(argsArray));
045  }
046
047  public StoragePolicyAdmin(Configuration conf) {
048    super(conf);
049  }
050
051  @Override
052  public int run(String[] args) throws Exception {
053    if (args.length == 0) {
054      AdminHelper.printUsage(false, "storagepolicies", COMMANDS);
055      return 1;
056    }
057    final AdminHelper.Command command = AdminHelper.determineCommand(args[0],
058        COMMANDS);
059    if (command == null) {
060      System.err.println("Can't understand command '" + args[0] + "'");
061      if (!args[0].startsWith("-")) {
062        System.err.println("Command names must start with dashes.");
063      }
064      AdminHelper.printUsage(false, "storagepolicies", COMMANDS);
065      return 1;
066    }
067    final List<String> argsList = new LinkedList<>();
068    argsList.addAll(Arrays.asList(args).subList(1, args.length));
069    try {
070      return command.run(getConf(), argsList);
071    } catch (IllegalArgumentException e) {
072      System.err.println(AdminHelper.prettifyException(e));
073      return -1;
074    }
075  }
076
077  /** Command to list all the existing storage policies */
078  private static class ListStoragePoliciesCommand
079      implements AdminHelper.Command {
080    @Override
081    public String getName() {
082      return "-listPolicies";
083    }
084
085    @Override
086    public String getShortUsage() {
087      return "[" + getName() + "]\n";
088    }
089
090    @Override
091    public String getLongUsage() {
092      return getShortUsage() + "\n" +
093          "List all the existing block storage policies.\n";
094    }
095
096    @Override
097    public int run(Configuration conf, List<String> args) throws IOException {
098      final DistributedFileSystem dfs = AdminHelper.getDFS(conf);
099      try {
100        BlockStoragePolicy[] policies = dfs.getStoragePolicies();
101        System.out.println("Block Storage Policies:");
102        for (BlockStoragePolicy policy : policies) {
103          if (policy != null) {
104            System.out.println("\t" + policy);
105          }
106        }
107      } catch (IOException e) {
108        System.err.println(AdminHelper.prettifyException(e));
109        return 2;
110      }
111      return 0;
112    }
113  }
114
115  /** Command to get the storage policy of a file/directory */
116  private static class GetStoragePolicyCommand implements AdminHelper.Command {
117    @Override
118    public String getName() {
119      return "-getStoragePolicy";
120    }
121
122    @Override
123    public String getShortUsage() {
124      return "[" + getName() + " -path <path>]\n";
125    }
126
127    @Override
128    public String getLongUsage() {
129      final TableListing listing = AdminHelper.getOptionDescriptionListing();
130      listing.addRow("<path>",
131          "The path of the file/directory for getting the storage policy");
132      return getShortUsage() + "\n" +
133          "Get the storage policy of a file/directory.\n\n" +
134          listing.toString();
135    }
136
137    @Override
138    public int run(Configuration conf, List<String> args) throws IOException {
139      final String path = StringUtils.popOptionWithArgument("-path", args);
140      if (path == null) {
141        System.err.println("Please specify the path with -path.\nUsage:" +
142            getLongUsage());
143        return 1;
144      }
145
146      final DistributedFileSystem dfs = AdminHelper.getDFS(conf);
147      try {
148        HdfsFileStatus status = dfs.getClient().getFileInfo(path);
149        if (status == null) {
150          System.err.println("File/Directory does not exist: " + path);
151          return 2;
152        }
153        byte storagePolicyId = status.getStoragePolicy();
154        if (storagePolicyId == BlockStoragePolicySuite.ID_UNSPECIFIED) {
155          System.out.println("The storage policy of " + path + " is unspecified");
156          return 0;
157        }
158        BlockStoragePolicy[] policies = dfs.getStoragePolicies();
159        for (BlockStoragePolicy p : policies) {
160          if (p.getId() == storagePolicyId) {
161            System.out.println("The storage policy of " + path + ":\n" + p);
162            return 0;
163          }
164        }
165      } catch (Exception e) {
166        System.err.println(AdminHelper.prettifyException(e));
167        return 2;
168      }
169      System.err.println("Cannot identify the storage policy for " + path);
170      return 2;
171    }
172  }
173
174  /** Command to set the storage policy to a file/directory */
175  private static class SetStoragePolicyCommand implements AdminHelper.Command {
176    @Override
177    public String getName() {
178      return "-setStoragePolicy";
179    }
180
181    @Override
182    public String getShortUsage() {
183      return "[" + getName() + " -path <path> -policy <policy>]\n";
184    }
185
186    @Override
187    public String getLongUsage() {
188      TableListing listing = AdminHelper.getOptionDescriptionListing();
189      listing.addRow("<path>", "The path of the file/directory to set storage" +
190          " policy");
191      listing.addRow("<policy>", "The name of the block storage policy");
192      return getShortUsage() + "\n" +
193          "Set the storage policy to a file/directory.\n\n" +
194          listing.toString();
195    }
196
197    @Override
198    public int run(Configuration conf, List<String> args) throws IOException {
199      final String path = StringUtils.popOptionWithArgument("-path", args);
200      if (path == null) {
201        System.err.println("Please specify the path for setting the storage " +
202            "policy.\nUsage: " + getLongUsage());
203        return 1;
204      }
205
206      final String policyName = StringUtils.popOptionWithArgument("-policy",
207          args);
208      if (policyName == null) {
209        System.err.println("Please specify the policy name.\nUsage: " +
210            getLongUsage());
211        return 1;
212      }
213
214      final DistributedFileSystem dfs = AdminHelper.getDFS(conf);
215      try {
216        dfs.setStoragePolicy(new Path(path), policyName);
217        System.out.println("Set storage policy " + policyName + " on " + path);
218      } catch (Exception e) {
219        System.err.println(AdminHelper.prettifyException(e));
220        return 2;
221      }
222      return 0;
223    }
224  }
225
226  private static final AdminHelper.Command[] COMMANDS = {
227      new ListStoragePoliciesCommand(),
228      new SetStoragePolicyCommand(),
229      new GetStoragePolicyCommand()
230  };
231}