kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [2/3] kudu git commit: tool: rename tablet mode to local_replica
Date Sat, 10 Sep 2016 00:59:18 GMT
tool: rename tablet mode to local_replica

The tablet mode isn't actually going away, we're just going to use it for
"remote operations that are scoped to an entire tablet".

Change-Id: I2022a49817bfa48b74c734fd849d92d1f15a697f
Reviewed-on: http://gerrit.cloudera.org:8080/4355
Reviewed-by: Todd Lipcon <todd@apache.org>
Tested-by: Kudu Jenkins


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/2e30b2a8
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/2e30b2a8
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/2e30b2a8

Branch: refs/heads/master
Commit: 2e30b2a8fca48d472143a9782b2f2449dcd6cfc2
Parents: b5fc3a6
Author: Adar Dembo <adar@cloudera.com>
Authored: Fri Sep 9 13:48:13 2016 -0700
Committer: Adar Dembo <adar@cloudera.com>
Committed: Sat Sep 10 00:48:34 2016 +0000

----------------------------------------------------------------------
 docs/release_notes.adoc                         |   2 +-
 .../integration-tests/master_failover-itest.cc  |   6 +-
 .../integration-tests/master_migration-itest.cc |   6 +-
 src/kudu/tools/CMakeLists.txt                   |   2 +-
 src/kudu/tools/kudu-tool-test.cc                |  13 +-
 src/kudu/tools/tool_action.h                    |   2 +-
 src/kudu/tools/tool_action_local_replica.cc     | 282 +++++++++++++++++++
 src/kudu/tools/tool_action_tablet.cc            | 282 -------------------
 src/kudu/tools/tool_main.cc                     |   2 +-
 9 files changed, 299 insertions(+), 298 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/docs/release_notes.adoc
----------------------------------------------------------------------
diff --git a/docs/release_notes.adoc b/docs/release_notes.adoc
index 9a431fc..2388bce 100644
--- a/docs/release_notes.adoc
+++ b/docs/release_notes.adoc
@@ -59,7 +59,7 @@ Kudu 1.0.0 are not supported.
   implemented as `kudu fs cfile_dump`.
 
 - The `log-dump` tool has been removed. The same functionality is now
-  implemented as `kudu wal dump` and `kudu tablet dump_wals`.
+  implemented as `kudu wal dump` and `kudu local_replica dump_wals`.
 
 - KuduSession methods in the C++ library are no longer advertised as thread-safe
   to have one set of semantics for both C++ and Java Kudu client libraries.

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/integration-tests/master_failover-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master_failover-itest.cc b/src/kudu/integration-tests/master_failover-itest.cc
index a2205c6..5063350 100644
--- a/src/kudu/integration-tests/master_failover-itest.cc
+++ b/src/kudu/integration-tests/master_failover-itest.cc
@@ -379,7 +379,7 @@ TEST_F(MasterFailoverTest, TestMasterPermanentFailure) {
     {
       vector<string> args = {
           kBinPath,
-          "tablet",
+          "local_replica",
           "cmeta",
           "print_replica_uuids",
           "--fs_wal_dir=" + other_master->data_dir(),
@@ -419,8 +419,8 @@ TEST_F(MasterFailoverTest, TestMasterPermanentFailure) {
     {
       vector<string> args = {
           kBinPath,
-          "tablet",
-          "copy",
+          "local_replica",
+          "copy_from_remote",
           "--fs_wal_dir=" + data_root,
           "--fs_data_dirs=" + data_root,
           master::SysCatalogTable::kSysCatalogTabletId,

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/integration-tests/master_migration-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master_migration-itest.cc b/src/kudu/integration-tests/master_migration-itest.cc
index ee9fb59..b01cda0 100644
--- a/src/kudu/integration-tests/master_migration-itest.cc
+++ b/src/kudu/integration-tests/master_migration-itest.cc
@@ -140,7 +140,7 @@ TEST_F(MasterMigrationTest, TestEndToEndMigration) {
     string data_root = cluster_->GetDataPath("master-0");
     vector<string> args = {
         kBinPath,
-        "tablet",
+        "local_replica",
         "cmeta",
         "rewrite_raft_config",
         "--fs_wal_dir=" + data_root,
@@ -168,8 +168,8 @@ TEST_F(MasterMigrationTest, TestEndToEndMigration) {
     string data_root = cluster_->GetDataPath(Substitute("master-$0", i));
     vector<string> args = {
         kBinPath,
-        "tablet",
-        "copy",
+        "local_replica",
+        "copy_from_remote",
         "--fs_wal_dir=" + data_root,
         "--fs_data_dirs=" + data_root,
         SysCatalogTable::kSysCatalogTabletId,

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/tools/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/tools/CMakeLists.txt b/src/kudu/tools/CMakeLists.txt
index c7c5a5f..9a029fb 100644
--- a/src/kudu/tools/CMakeLists.txt
+++ b/src/kudu/tools/CMakeLists.txt
@@ -89,8 +89,8 @@ add_executable(kudu
   tool_action_cluster.cc
   tool_action_common.cc
   tool_action_fs.cc
+  tool_action_local_replica.cc
   tool_action_pbc.cc
-  tool_action_tablet.cc
   tool_action_wal.cc
   tool_main.cc
 )

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/tools/kudu-tool-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index b018f3b..89a0725 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -167,8 +167,8 @@ TEST_F(ToolTest, TestTopLevelHelp) {
   const vector<string> kTopLevelRegexes = {
       "cluster.*Kudu cluster",
       "fs.*Kudu filesystem",
+      "local_replica.*Kudu replicas",
       "pbc.*protobuf container",
-      "tablet.*Kudu replica",
       "wal.*write-ahead log"
   };
   NO_FATALS(RunTestHelp("", kTopLevelRegexes));
@@ -188,19 +188,19 @@ TEST_F(ToolTest, TestModeHelp) {
                           Status::InvalidArgument("unknown command 'not_a_mode'")));
   }
   {
-    const vector<string> kTabletModeRegexes = {
+    const vector<string> kLocalReplicaModeRegexes = {
         "cmeta.*consensus metadata file",
-        "copy.*Copy a replica",
+        "copy_from_remote.*Copy a replica",
         "dump_wals.*Dump all WAL"
     };
-    NO_FATALS(RunTestHelp("tablet", kTabletModeRegexes));
+    NO_FATALS(RunTestHelp("local_replica", kLocalReplicaModeRegexes));
   }
   {
     const vector<string> kCmetaModeRegexes = {
         "print_replica_uuids.*Print all replica UUIDs",
         "rewrite_raft_config.*Rewrite a replica"
     };
-    NO_FATALS(RunTestHelp("tablet cmeta", kCmetaModeRegexes));
+    NO_FATALS(RunTestHelp("local_replica cmeta", kCmetaModeRegexes));
   }
   {
     const vector<string> kClusterModeRegexes = {
@@ -404,7 +404,8 @@ TEST_F(ToolTest, TestWalDump) {
   string wal_path = fs.GetWalSegmentFileName(kTestTablet, 1);
   string stdout;
   for (const auto& args : { Substitute("wal dump $0", wal_path),
-                            Substitute("tablet dump_wals --fs_wal_dir=$0 $1", kTestDir, kTestTablet)
+                            Substitute("local_replica dump_wals --fs_wal_dir=$0 $1",
+                                       kTestDir, kTestTablet)
                            }) {
     SCOPED_TRACE(args);
     for (const auto& print_entries : { "true", "1", "yes", "decoded" }) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/tools/tool_action.h
----------------------------------------------------------------------
diff --git a/src/kudu/tools/tool_action.h b/src/kudu/tools/tool_action.h
index e8bdc90..1730a1d 100644
--- a/src/kudu/tools/tool_action.h
+++ b/src/kudu/tools/tool_action.h
@@ -274,8 +274,8 @@ class Action {
 // Returns new nodes for each major mode.
 std::unique_ptr<Mode> BuildClusterMode();
 std::unique_ptr<Mode> BuildFsMode();
+std::unique_ptr<Mode> BuildLocalReplicaMode();
 std::unique_ptr<Mode> BuildPbcMode();
-std::unique_ptr<Mode> BuildTabletMode();
 std::unique_ptr<Mode> BuildWalMode();
 
 } // namespace tools

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/tools/tool_action_local_replica.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/tool_action_local_replica.cc b/src/kudu/tools/tool_action_local_replica.cc
new file mode 100644
index 0000000..17aecaf
--- /dev/null
+++ b/src/kudu/tools/tool_action_local_replica.cc
@@ -0,0 +1,282 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "kudu/tools/tool_action.h"
+
+#include <iostream>
+#include <list>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "kudu/common/wire_protocol.h"
+#include "kudu/consensus/consensus_meta.h"
+#include "kudu/consensus/log_index.h"
+#include "kudu/consensus/log_reader.h"
+#include "kudu/consensus/log_util.h"
+#include "kudu/fs/fs_manager.h"
+#include "kudu/gutil/map-util.h"
+#include "kudu/gutil/ref_counted.h"
+#include "kudu/gutil/strings/join.h"
+#include "kudu/gutil/strings/split.h"
+#include "kudu/gutil/strings/stringpiece.h"
+#include "kudu/gutil/strings/substitute.h"
+#include "kudu/master/sys_catalog.h"
+#include "kudu/rpc/messenger.h"
+#include "kudu/tools/tool_action_common.h"
+#include "kudu/tserver/tablet_copy_client.h"
+#include "kudu/util/env.h"
+#include "kudu/util/env_util.h"
+#include "kudu/util/metrics.h"
+#include "kudu/util/net/net_util.h"
+#include "kudu/util/status.h"
+
+namespace kudu {
+namespace tools {
+
+using consensus::ConsensusMetadata;
+using consensus::RaftConfigPB;
+using consensus::RaftPeerPB;
+using log::LogIndex;
+using log::LogReader;
+using log::ReadableLogSegment;
+using log::SegmentSequence;
+using rpc::Messenger;
+using rpc::MessengerBuilder;
+using std::cout;
+using std::endl;
+using std::list;
+using std::shared_ptr;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+using strings::Split;
+using strings::Substitute;
+using tserver::TabletCopyClient;
+
+namespace {
+
+// Parses a colon-delimited string containing a hostname or IP address and port
+// into its respective parts. For example, "localhost:12345" parses into
+// hostname=localhost, and port=12345.
+//
+// Does not allow a port with value 0.
+Status ParseHostPortString(const string& hostport_str, HostPort* hostport) {
+  HostPort hp;
+  Status s = hp.ParseString(hostport_str, 0);
+  if (!s.ok()) {
+    return s.CloneAndPrepend(Substitute(
+        "error while parsing peer '$0'", hostport_str));
+  }
+  if (hp.port() == 0) {
+    return Status::InvalidArgument(
+        Substitute("peer '$0' has port of 0", hostport_str));
+  }
+  *hostport = hp;
+  return Status::OK();
+}
+
+// Parses a colon-delimited string containing a uuid, hostname or IP address,
+// and port into its respective parts. For example,
+// "1c7f19e7ecad4f918c0d3d23180fdb18:localhost:12345" parses into
+// uuid=1c7f19e7ecad4f918c0d3d23180fdb18, hostname=localhost, and port=12345.
+Status ParsePeerString(const string& peer_str,
+                       string* uuid,
+                       HostPort* hostport) {
+  string::size_type first_colon_idx = peer_str.find(":");
+  if (first_colon_idx == string::npos) {
+    return Status::InvalidArgument(Substitute("bad peer '$0'", peer_str));
+  }
+  string hostport_str = peer_str.substr(first_colon_idx + 1);
+  RETURN_NOT_OK(ParseHostPortString(hostport_str, hostport));
+  *uuid = peer_str.substr(0, first_colon_idx);
+  return Status::OK();
+}
+
+Status PrintReplicaUuids(const RunnerContext& context) {
+  string tablet_id = FindOrDie(context.required_args, "tablet_id");
+
+  FsManagerOpts opts;
+  opts.read_only = true;
+  FsManager fs_manager(Env::Default(), opts);
+  RETURN_NOT_OK(fs_manager.Open());
+
+  // Load the cmeta file and print all peer uuids.
+  unique_ptr<ConsensusMetadata> cmeta;
+  RETURN_NOT_OK(ConsensusMetadata::Load(&fs_manager, tablet_id,
+                                        fs_manager.uuid(), &cmeta));
+  cout << JoinMapped(cmeta->committed_config().peers(),
+                     [](const RaftPeerPB& p){ return p.permanent_uuid(); },
+                     " ") << endl;
+  return Status::OK();
+}
+
+Status RewriteRaftConfig(const RunnerContext& context) {
+  // Parse tablet ID argument.
+  string tablet_id = FindOrDie(context.required_args, "tablet_id");
+  if (tablet_id != master::SysCatalogTable::kSysCatalogTabletId) {
+    LOG(WARNING) << "Master will not notice rewritten Raft config of regular "
+                 << "tablets. A regular Raft config change must occur.";
+  }
+
+  // Parse peer arguments.
+  vector<pair<string, HostPort>> peers;
+  for (const auto& arg : context.variadic_args) {
+    pair<string, HostPort> parsed_peer;
+    RETURN_NOT_OK(ParsePeerString(arg,
+                                  &parsed_peer.first, &parsed_peer.second));
+    peers.push_back(parsed_peer);
+  }
+  DCHECK(!peers.empty());
+
+  // Make a copy of the old file before rewriting it.
+  Env* env = Env::Default();
+  FsManager fs_manager(env, FsManagerOpts());
+  RETURN_NOT_OK(fs_manager.Open());
+  string cmeta_filename = fs_manager.GetConsensusMetadataPath(tablet_id);
+  string backup_filename = Substitute("$0.pre_rewrite.$1",
+                                      cmeta_filename, env->NowMicros());
+  WritableFileOptions opts;
+  opts.mode = Env::CREATE_NON_EXISTING;
+  opts.sync_on_close = true;
+  RETURN_NOT_OK(env_util::CopyFile(env, cmeta_filename, backup_filename, opts));
+  LOG(INFO) << "Backed up current config to " << backup_filename;
+
+  // Load the cmeta file and rewrite the raft config.
+  unique_ptr<ConsensusMetadata> cmeta;
+  RETURN_NOT_OK(ConsensusMetadata::Load(&fs_manager, tablet_id,
+                                        fs_manager.uuid(), &cmeta));
+  RaftConfigPB current_config = cmeta->committed_config();
+  RaftConfigPB new_config = current_config;
+  new_config.clear_peers();
+  for (const auto& p : peers) {
+    RaftPeerPB new_peer;
+    new_peer.set_member_type(RaftPeerPB::VOTER);
+    new_peer.set_permanent_uuid(p.first);
+    HostPortPB new_peer_host_port_pb;
+    RETURN_NOT_OK(HostPortToPB(p.second, &new_peer_host_port_pb));
+    new_peer.mutable_last_known_addr()->CopyFrom(new_peer_host_port_pb);
+    new_config.add_peers()->CopyFrom(new_peer);
+  }
+  cmeta->set_committed_config(new_config);
+  return cmeta->Flush();
+}
+
+Status CopyFromRemote(const RunnerContext& context) {
+  // Parse the tablet ID and source arguments.
+  string tablet_id = FindOrDie(context.required_args, "tablet_id");
+  string rpc_address = FindOrDie(context.required_args, "source");
+
+  HostPort hp;
+  RETURN_NOT_OK(ParseHostPortString(rpc_address, &hp));
+
+  // Copy the tablet over.
+  FsManager fs_manager(Env::Default(), FsManagerOpts());
+  RETURN_NOT_OK(fs_manager.Open());
+  MessengerBuilder builder("tablet_copy_client");
+  shared_ptr<Messenger> messenger;
+  builder.Build(&messenger);
+  TabletCopyClient client(tablet_id, &fs_manager, messenger);
+  RETURN_NOT_OK(client.Start(hp, nullptr));
+  RETURN_NOT_OK(client.FetchAll(nullptr));
+  return client.Finish();
+}
+
+Status DumpWals(const RunnerContext& context) {
+  string tablet_id = FindOrDie(context.required_args, "tablet_id");
+
+  FsManagerOpts fs_opts;
+  fs_opts.read_only = true;
+  FsManager fs_manager(Env::Default(), fs_opts);
+  RETURN_NOT_OK(fs_manager.Open());
+
+  shared_ptr<LogReader> reader;
+  RETURN_NOT_OK(LogReader::Open(&fs_manager,
+                                scoped_refptr<LogIndex>(),
+                                tablet_id,
+                                scoped_refptr<MetricEntity>(),
+                                &reader));
+
+  SegmentSequence segments;
+  RETURN_NOT_OK(reader->GetSegmentsSnapshot(&segments));
+
+  for (const scoped_refptr<ReadableLogSegment>& segment : segments) {
+    RETURN_NOT_OK(PrintSegment(segment));
+  }
+
+  return Status::OK();
+}
+
+} // anonymous namespace
+
+unique_ptr<Mode> BuildLocalReplicaMode() {
+  unique_ptr<Action> print_replica_uuids =
+      ActionBuilder("print_replica_uuids", &PrintReplicaUuids)
+      .Description("Print all replica UUIDs found in a tablet's Raft configuration")
+      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
+      .AddOptionalParameter("fs_wal_dir")
+      .AddOptionalParameter("fs_data_dirs")
+      .Build();
+
+  unique_ptr<Action> rewrite_raft_config =
+      ActionBuilder("rewrite_raft_config", &RewriteRaftConfig)
+      .Description("Rewrite a replica's Raft configuration")
+      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
+      .AddRequiredVariadicParameter({
+        "peers", "List of peers where each peer is of form uuid:hostname:port" })
+      .AddOptionalParameter("fs_wal_dir")
+      .AddOptionalParameter("fs_data_dirs")
+      .Build();
+
+  unique_ptr<Mode> cmeta =
+      ModeBuilder("cmeta")
+      .Description("Operate on a local Kudu tablet's consensus metadata file")
+      .AddAction(std::move(print_replica_uuids))
+      .AddAction(std::move(rewrite_raft_config))
+      .Build();
+
+  unique_ptr<Action> copy_from_remote =
+      ActionBuilder("copy_from_remote", &CopyFromRemote)
+      .Description("Copy a replica from a remote server")
+      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
+      .AddRequiredParameter({ "source", "Source RPC address of form hostname:port" })
+      .AddOptionalParameter("fs_wal_dir")
+      .AddOptionalParameter("fs_data_dirs")
+      .Build();
+
+  unique_ptr<Action> dump_wals =
+      ActionBuilder("dump_wals", &DumpWals)
+      .Description("Dump all WAL (write-ahead log) segments of a tablet")
+      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
+      .AddOptionalParameter("fs_wal_dir")
+      .AddOptionalParameter("fs_data_dirs")
+      .AddOptionalParameter("print_entries")
+      .AddOptionalParameter("print_meta")
+      .AddOptionalParameter("truncate_data")
+      .Build();
+
+  return ModeBuilder("local_replica")
+      .Description("Operate on local Kudu replicas via the local filesystem")
+      .AddMode(std::move(cmeta))
+      .AddAction(std::move(copy_from_remote))
+      .AddAction(std::move(dump_wals))
+      .Build();
+}
+
+} // namespace tools
+} // namespace kudu
+

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/tools/tool_action_tablet.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/tool_action_tablet.cc b/src/kudu/tools/tool_action_tablet.cc
deleted file mode 100644
index 736c2e5..0000000
--- a/src/kudu/tools/tool_action_tablet.cc
+++ /dev/null
@@ -1,282 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#include "kudu/tools/tool_action.h"
-
-#include <iostream>
-#include <list>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "kudu/common/wire_protocol.h"
-#include "kudu/consensus/consensus_meta.h"
-#include "kudu/consensus/log_index.h"
-#include "kudu/consensus/log_reader.h"
-#include "kudu/consensus/log_util.h"
-#include "kudu/fs/fs_manager.h"
-#include "kudu/gutil/map-util.h"
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/gutil/strings/join.h"
-#include "kudu/gutil/strings/split.h"
-#include "kudu/gutil/strings/stringpiece.h"
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/master/sys_catalog.h"
-#include "kudu/rpc/messenger.h"
-#include "kudu/tools/tool_action_common.h"
-#include "kudu/tserver/tablet_copy_client.h"
-#include "kudu/util/env.h"
-#include "kudu/util/env_util.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/net/net_util.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-namespace tools {
-
-using consensus::ConsensusMetadata;
-using consensus::RaftConfigPB;
-using consensus::RaftPeerPB;
-using log::LogIndex;
-using log::LogReader;
-using log::ReadableLogSegment;
-using log::SegmentSequence;
-using rpc::Messenger;
-using rpc::MessengerBuilder;
-using std::cout;
-using std::endl;
-using std::list;
-using std::shared_ptr;
-using std::string;
-using std::unique_ptr;
-using std::vector;
-using strings::Split;
-using strings::Substitute;
-using tserver::TabletCopyClient;
-
-namespace {
-
-// Parses a colon-delimited string containing a hostname or IP address and port
-// into its respective parts. For example, "localhost:12345" parses into
-// hostname=localhost, and port=12345.
-//
-// Does not allow a port with value 0.
-Status ParseHostPortString(const string& hostport_str, HostPort* hostport) {
-  HostPort hp;
-  Status s = hp.ParseString(hostport_str, 0);
-  if (!s.ok()) {
-    return s.CloneAndPrepend(Substitute(
-        "error while parsing peer '$0'", hostport_str));
-  }
-  if (hp.port() == 0) {
-    return Status::InvalidArgument(
-        Substitute("peer '$0' has port of 0", hostport_str));
-  }
-  *hostport = hp;
-  return Status::OK();
-}
-
-// Parses a colon-delimited string containing a uuid, hostname or IP address,
-// and port into its respective parts. For example,
-// "1c7f19e7ecad4f918c0d3d23180fdb18:localhost:12345" parses into
-// uuid=1c7f19e7ecad4f918c0d3d23180fdb18, hostname=localhost, and port=12345.
-Status ParsePeerString(const string& peer_str,
-                       string* uuid,
-                       HostPort* hostport) {
-  string::size_type first_colon_idx = peer_str.find(":");
-  if (first_colon_idx == string::npos) {
-    return Status::InvalidArgument(Substitute("bad peer '$0'", peer_str));
-  }
-  string hostport_str = peer_str.substr(first_colon_idx + 1);
-  RETURN_NOT_OK(ParseHostPortString(hostport_str, hostport));
-  *uuid = peer_str.substr(0, first_colon_idx);
-  return Status::OK();
-}
-
-Status PrintReplicaUuids(const RunnerContext& context) {
-  string tablet_id = FindOrDie(context.required_args, "tablet_id");
-
-  FsManagerOpts opts;
-  opts.read_only = true;
-  FsManager fs_manager(Env::Default(), opts);
-  RETURN_NOT_OK(fs_manager.Open());
-
-  // Load the cmeta file and print all peer uuids.
-  unique_ptr<ConsensusMetadata> cmeta;
-  RETURN_NOT_OK(ConsensusMetadata::Load(&fs_manager, tablet_id,
-                                        fs_manager.uuid(), &cmeta));
-  cout << JoinMapped(cmeta->committed_config().peers(),
-                     [](const RaftPeerPB& p){ return p.permanent_uuid(); },
-                     " ") << endl;
-  return Status::OK();
-}
-
-Status RewriteRaftConfig(const RunnerContext& context) {
-  // Parse tablet ID argument.
-  string tablet_id = FindOrDie(context.required_args, "tablet_id");
-  if (tablet_id != master::SysCatalogTable::kSysCatalogTabletId) {
-    LOG(WARNING) << "Master will not notice rewritten Raft config of regular "
-                 << "tablets. A regular Raft config change must occur.";
-  }
-
-  // Parse peer arguments.
-  vector<pair<string, HostPort>> peers;
-  for (const auto& arg : context.variadic_args) {
-    pair<string, HostPort> parsed_peer;
-    RETURN_NOT_OK(ParsePeerString(arg,
-                                  &parsed_peer.first, &parsed_peer.second));
-    peers.push_back(parsed_peer);
-  }
-  DCHECK(!peers.empty());
-
-  // Make a copy of the old file before rewriting it.
-  Env* env = Env::Default();
-  FsManager fs_manager(env, FsManagerOpts());
-  RETURN_NOT_OK(fs_manager.Open());
-  string cmeta_filename = fs_manager.GetConsensusMetadataPath(tablet_id);
-  string backup_filename = Substitute("$0.pre_rewrite.$1",
-                                      cmeta_filename, env->NowMicros());
-  WritableFileOptions opts;
-  opts.mode = Env::CREATE_NON_EXISTING;
-  opts.sync_on_close = true;
-  RETURN_NOT_OK(env_util::CopyFile(env, cmeta_filename, backup_filename, opts));
-  LOG(INFO) << "Backed up current config to " << backup_filename;
-
-  // Load the cmeta file and rewrite the raft config.
-  unique_ptr<ConsensusMetadata> cmeta;
-  RETURN_NOT_OK(ConsensusMetadata::Load(&fs_manager, tablet_id,
-                                        fs_manager.uuid(), &cmeta));
-  RaftConfigPB current_config = cmeta->committed_config();
-  RaftConfigPB new_config = current_config;
-  new_config.clear_peers();
-  for (const auto& p : peers) {
-    RaftPeerPB new_peer;
-    new_peer.set_member_type(RaftPeerPB::VOTER);
-    new_peer.set_permanent_uuid(p.first);
-    HostPortPB new_peer_host_port_pb;
-    RETURN_NOT_OK(HostPortToPB(p.second, &new_peer_host_port_pb));
-    new_peer.mutable_last_known_addr()->CopyFrom(new_peer_host_port_pb);
-    new_config.add_peers()->CopyFrom(new_peer);
-  }
-  cmeta->set_committed_config(new_config);
-  return cmeta->Flush();
-}
-
-Status Copy(const RunnerContext& context) {
-  // Parse the tablet ID and source arguments.
-  string tablet_id = FindOrDie(context.required_args, "tablet_id");
-  string rpc_address = FindOrDie(context.required_args, "source");
-
-  HostPort hp;
-  RETURN_NOT_OK(ParseHostPortString(rpc_address, &hp));
-
-  // Copy the tablet over.
-  FsManager fs_manager(Env::Default(), FsManagerOpts());
-  RETURN_NOT_OK(fs_manager.Open());
-  MessengerBuilder builder("tablet_copy_client");
-  shared_ptr<Messenger> messenger;
-  builder.Build(&messenger);
-  TabletCopyClient client(tablet_id, &fs_manager, messenger);
-  RETURN_NOT_OK(client.Start(hp, nullptr));
-  RETURN_NOT_OK(client.FetchAll(nullptr));
-  return client.Finish();
-}
-
-Status DumpWals(const RunnerContext& context) {
-  string tablet_id = FindOrDie(context.required_args, "tablet_id");
-
-  FsManagerOpts fs_opts;
-  fs_opts.read_only = true;
-  FsManager fs_manager(Env::Default(), fs_opts);
-  RETURN_NOT_OK(fs_manager.Open());
-
-  shared_ptr<LogReader> reader;
-  RETURN_NOT_OK(LogReader::Open(&fs_manager,
-                                scoped_refptr<LogIndex>(),
-                                tablet_id,
-                                scoped_refptr<MetricEntity>(),
-                                &reader));
-
-  SegmentSequence segments;
-  RETURN_NOT_OK(reader->GetSegmentsSnapshot(&segments));
-
-  for (const scoped_refptr<ReadableLogSegment>& segment : segments) {
-    RETURN_NOT_OK(PrintSegment(segment));
-  }
-
-  return Status::OK();
-}
-
-} // anonymous namespace
-
-unique_ptr<Mode> BuildTabletMode() {
-  unique_ptr<Action> print_replica_uuids =
-      ActionBuilder("print_replica_uuids", &PrintReplicaUuids)
-      .Description("Print all replica UUIDs found in a tablet's Raft configuration")
-      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
-      .AddOptionalParameter("fs_wal_dir")
-      .AddOptionalParameter("fs_data_dirs")
-      .Build();
-
-  unique_ptr<Action> rewrite_raft_config =
-      ActionBuilder("rewrite_raft_config", &RewriteRaftConfig)
-      .Description("Rewrite a replica's Raft configuration")
-      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
-      .AddRequiredVariadicParameter({
-        "peers", "List of peers where each peer is of form uuid:hostname:port" })
-      .AddOptionalParameter("fs_wal_dir")
-      .AddOptionalParameter("fs_data_dirs")
-      .Build();
-
-  unique_ptr<Mode> cmeta =
-      ModeBuilder("cmeta")
-      .Description("Operate on a local Kudu tablet's consensus metadata file")
-      .AddAction(std::move(print_replica_uuids))
-      .AddAction(std::move(rewrite_raft_config))
-      .Build();
-
-  unique_ptr<Action> copy =
-      ActionBuilder("copy", &Copy)
-      .Description("Copy a replica from a remote server")
-      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
-      .AddRequiredParameter({ "source", "Source RPC address of form hostname:port" })
-      .AddOptionalParameter("fs_wal_dir")
-      .AddOptionalParameter("fs_data_dirs")
-      .Build();
-
-  unique_ptr<Action> dump_wals =
-      ActionBuilder("dump_wals", &DumpWals)
-      .Description("Dump all WAL (write-ahead log) segments of a tablet")
-      .AddRequiredParameter({ "tablet_id", "Tablet identifier" })
-      .AddOptionalParameter("fs_wal_dir")
-      .AddOptionalParameter("fs_data_dirs")
-      .AddOptionalParameter("print_entries")
-      .AddOptionalParameter("print_meta")
-      .AddOptionalParameter("truncate_data")
-      .Build();
-
-  return ModeBuilder("tablet")
-      .Description("Operate on a local Kudu replica")
-      .AddMode(std::move(cmeta))
-      .AddAction(std::move(copy))
-      .AddAction(std::move(dump_wals))
-      .Build();
-}
-
-} // namespace tools
-} // namespace kudu
-

http://git-wip-us.apache.org/repos/asf/kudu/blob/2e30b2a8/src/kudu/tools/tool_main.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/tool_main.cc b/src/kudu/tools/tool_main.cc
index f1fbe93..c18065d 100644
--- a/src/kudu/tools/tool_main.cc
+++ b/src/kudu/tools/tool_main.cc
@@ -113,8 +113,8 @@ int RunTool(int argc, char** argv, bool show_help) {
     .Description("doesn't matter") // root mode description isn't printed
     .AddMode(BuildClusterMode())
     .AddMode(BuildFsMode())
+    .AddMode(BuildLocalReplicaMode())
     .AddMode(BuildPbcMode())
-    .AddMode(BuildTabletMode())
     .AddMode(BuildWalMode())
     .Build();
 


Mime
View raw message