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.hbase.backup;
019
020import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_BACKUP_LIST_DESC;
021import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_BANDWIDTH;
022import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_BANDWIDTH_DESC;
023import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_DEBUG;
024import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_DEBUG_DESC;
025import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_IGNORECHECKSUM;
026import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_IGNORECHECKSUM_DESC;
027import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_KEEP;
028import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_KEEP_DESC;
029import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_LIST;
030import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_PATH;
031import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_PATH_DESC;
032import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_RECORD_NUMBER;
033import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_RECORD_NUMBER_DESC;
034import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_SET;
035import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_SET_DESC;
036import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE;
037import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE_DESC;
038import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_WORKERS;
039import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_WORKERS_DESC;
040import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_YARN_QUEUE_NAME;
041import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_YARN_QUEUE_NAME_DESC;
042
043import java.io.IOException;
044import java.net.URI;
045import java.util.Objects;
046import org.apache.hadoop.conf.Configuration;
047import org.apache.hadoop.fs.Path;
048import org.apache.hadoop.hbase.HBaseConfiguration;
049import org.apache.hadoop.hbase.backup.BackupRestoreConstants.BackupCommand;
050import org.apache.hadoop.hbase.backup.impl.BackupCommands;
051import org.apache.hadoop.hbase.backup.impl.BackupManager;
052import org.apache.hadoop.hbase.logging.Log4jUtils;
053import org.apache.hadoop.hbase.util.AbstractHBaseTool;
054import org.apache.hadoop.hbase.util.CommonFSUtils;
055import org.apache.hadoop.util.ToolRunner;
056import org.apache.yetus.audience.InterfaceAudience;
057import org.slf4j.Logger;
058import org.slf4j.LoggerFactory;
059
060import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
061
062/**
063 * Command-line entry point for backup operation
064 */
065@InterfaceAudience.Private
066public class BackupDriver extends AbstractHBaseTool {
067
068  private static final Logger LOG = LoggerFactory.getLogger(BackupDriver.class);
069  private CommandLine cmd;
070
071  public BackupDriver() throws IOException {
072    init();
073  }
074
075  protected void init() throws IOException {
076    // disable irrelevant loggers to avoid it mess up command output
077    Log4jUtils.disableZkAndClientLoggers();
078  }
079
080  private int parseAndRun(String[] args) throws IOException {
081
082    // Check if backup is enabled
083    if (!BackupManager.isBackupEnabled(getConf())) {
084      System.err.println(BackupRestoreConstants.ENABLE_BACKUP);
085      return -1;
086    }
087
088    String cmd = null;
089    String[] remainArgs = null;
090    if (args == null || args.length == 0) {
091      printToolUsage();
092      return -1;
093    } else {
094      cmd = args[0];
095      remainArgs = new String[args.length - 1];
096      if (args.length > 1) {
097        System.arraycopy(args, 1, remainArgs, 0, args.length - 1);
098      }
099    }
100
101    BackupCommand type = BackupCommand.HELP;
102    if (BackupCommand.CREATE.name().equalsIgnoreCase(cmd)) {
103      type = BackupCommand.CREATE;
104    } else if (BackupCommand.HELP.name().equalsIgnoreCase(cmd)) {
105      type = BackupCommand.HELP;
106    } else if (BackupCommand.DELETE.name().equalsIgnoreCase(cmd)) {
107      type = BackupCommand.DELETE;
108    } else if (BackupCommand.DESCRIBE.name().equalsIgnoreCase(cmd)) {
109      type = BackupCommand.DESCRIBE;
110    } else if (BackupCommand.HISTORY.name().equalsIgnoreCase(cmd)) {
111      type = BackupCommand.HISTORY;
112    } else if (BackupCommand.PROGRESS.name().equalsIgnoreCase(cmd)) {
113      type = BackupCommand.PROGRESS;
114    } else if (BackupCommand.SET.name().equalsIgnoreCase(cmd)) {
115      type = BackupCommand.SET;
116    } else if (BackupCommand.REPAIR.name().equalsIgnoreCase(cmd)) {
117      type = BackupCommand.REPAIR;
118    } else if (BackupCommand.MERGE.name().equalsIgnoreCase(cmd)) {
119      type = BackupCommand.MERGE;
120    } else {
121      System.out.println("Unsupported command for backup: " + cmd);
122      printToolUsage();
123      return -1;
124    }
125
126    // enable debug logging
127    if (this.cmd.hasOption(OPTION_DEBUG)) {
128      Log4jUtils.setLogLevel("org.apache.hadoop.hbase.backup", "DEBUG");
129    }
130
131    BackupCommands.Command command = BackupCommands.createCommand(getConf(), type, this.cmd);
132    if (type == BackupCommand.CREATE && conf != null) {
133      ((BackupCommands.CreateCommand) command).setConf(conf);
134    }
135    try {
136      command.execute();
137    } catch (IOException e) {
138      if (e.getMessage().equals(BackupCommands.INCORRECT_USAGE)) {
139        return -1;
140      }
141      throw e;
142    } finally {
143      command.finish();
144    }
145    return 0;
146  }
147
148  @Override
149  protected void addOptions() {
150    // define supported options
151    addOptNoArg(OPTION_DEBUG, OPTION_DEBUG_DESC);
152    addOptWithArg(OPTION_TABLE, OPTION_TABLE_DESC);
153    addOptWithArg(OPTION_BANDWIDTH, OPTION_BANDWIDTH_DESC);
154    addOptWithArg(OPTION_LIST, OPTION_BACKUP_LIST_DESC);
155    addOptWithArg(OPTION_WORKERS, OPTION_WORKERS_DESC);
156    addOptNoArg(OPTION_IGNORECHECKSUM, OPTION_IGNORECHECKSUM_DESC);
157    addOptWithArg(OPTION_RECORD_NUMBER, OPTION_RECORD_NUMBER_DESC);
158    addOptWithArg(OPTION_SET, OPTION_SET_DESC);
159    addOptWithArg(OPTION_PATH, OPTION_PATH_DESC);
160    addOptWithArg(OPTION_KEEP, OPTION_KEEP_DESC);
161    addOptWithArg(OPTION_YARN_QUEUE_NAME, OPTION_YARN_QUEUE_NAME_DESC);
162
163  }
164
165  @Override
166  protected void processOptions(CommandLine cmd) {
167    this.cmd = cmd;
168  }
169
170  @Override
171  protected int doWork() throws Exception {
172    return parseAndRun(cmd.getArgs());
173  }
174
175  public static void main(String[] args) throws Exception {
176    Configuration conf = HBaseConfiguration.create();
177    Path hbasedir = CommonFSUtils.getRootDir(conf);
178    URI defaultFs = hbasedir.getFileSystem(conf).getUri();
179    CommonFSUtils.setFsDefault(conf, new Path(defaultFs));
180    int ret = ToolRunner.run(conf, new BackupDriver(), args);
181    System.exit(ret);
182  }
183
184  @Override
185  public int run(String[] args) throws IOException {
186    Objects.requireNonNull(conf, "Tool configuration is not initialized");
187
188    CommandLine cmd;
189    try {
190      // parse the command line arguments
191      cmd = parseArgs(args);
192      cmdLineArgs = args;
193    } catch (Exception e) {
194      System.err.println("Error when parsing command-line arguments: " + e.getMessage());
195      printToolUsage();
196      return EXIT_FAILURE;
197    }
198    processOptions(cmd);
199
200    int ret = EXIT_FAILURE;
201    try {
202      ret = doWork();
203    } catch (Exception e) {
204      LOG.error("Error running command-line tool", e);
205      return EXIT_FAILURE;
206    }
207    return ret;
208  }
209
210  protected void printToolUsage() throws IOException {
211    System.out.println(BackupCommands.USAGE);
212    System.out.println(BackupRestoreConstants.VERIFY_BACKUP);
213  }
214}