You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2014/02/15 02:17:30 UTC
[1/4] git commit: Added valgrind runnables.
Repository: mesos
Updated Branches:
refs/heads/master 8a4ec2e09 -> 165dbe101
Added valgrind runnables.
Adds valgrind runnables for executing memory / leak checks on mesos.
The runnables accept an additional parameter (-t) for selecting a
valgrind tool. The default (no option given) is memcheck. All other
parameters are passed on to the given target (master, slave, tests,
local).
Example: build/bin/valgrind-mesos-tests.sh -t helgrind
Review: https://reviews.apache.org/r/17636
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/36c7a4d7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/36c7a4d7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/36c7a4d7
Branch: refs/heads/master
Commit: 36c7a4d7e366c9b421bd8a092cce9f028c091cd3
Parents: 8a4ec2e
Author: TILL TOENSHOFF <to...@me.com>
Authored: Fri Feb 14 16:59:00 2014 -0800
Committer: Vinod Kone <vi...@twitter.com>
Committed: Fri Feb 14 16:59:00 2014 -0800
----------------------------------------------------------------------
bin/valgrind-mesos-local.sh.in | 53 ++++++++++++++++++++++++++++++++++++
bin/valgrind-mesos-master.sh.in | 53 ++++++++++++++++++++++++++++++++++++
bin/valgrind-mesos-slave.sh.in | 53 ++++++++++++++++++++++++++++++++++++
bin/valgrind-mesos-tests.sh.in | 53 ++++++++++++++++++++++++++++++++++++
configure.ac | 12 ++++++--
5 files changed, 222 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/36c7a4d7/bin/valgrind-mesos-local.sh.in
----------------------------------------------------------------------
diff --git a/bin/valgrind-mesos-local.sh.in b/bin/valgrind-mesos-local.sh.in
new file mode 100644
index 0000000..b7a04d1
--- /dev/null
+++ b/bin/valgrind-mesos-local.sh.in
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+# 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.
+
+# This is a wrapper for running valgrind on mesos-local before it is
+# installed that first sets up some flags via environment variables.
+
+# Use colors for errors.
+. @abs_top_srcdir@/support/colors.sh
+
+# Default valgrind tool is "memcheck".
+VALGRINDTOOL=memcheck
+
+# For supplying alternative tools (e.g. "helgrind"), use the -t option.
+while getopts ":t:" opt
+do
+ case "${opt}" in
+ t) VALGRINDTOOL=${OPTARG}; shift 2
+ ;;
+ esac
+done
+
+LIBTOOL=@abs_top_builddir@/libtool
+
+test ! -e ${LIBTOOL} && \
+ echo "${RED}Failed to find ${LIBTOOL}, have you run configure?${NORMAL}" \
+ && exit 1
+
+# Confirm libtool has "valgrind" support.
+${LIBTOOL} --mode=execute valgrind --version >/dev/null 2>&1
+
+test $? != 0 && \
+ echo "${RED}Generated libtool doesn't appear to support valgrind${NORMAL}" \
+ && exit 1
+
+. @abs_top_builddir@/bin/mesos-local-flags.sh
+
+exec ${LIBTOOL} --mode=execute valgrind --tool=${VALGRINDTOOL} \
+ @abs_top_builddir@/src/mesos-local "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/36c7a4d7/bin/valgrind-mesos-master.sh.in
----------------------------------------------------------------------
diff --git a/bin/valgrind-mesos-master.sh.in b/bin/valgrind-mesos-master.sh.in
new file mode 100644
index 0000000..21314af
--- /dev/null
+++ b/bin/valgrind-mesos-master.sh.in
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+# 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.
+
+# This is a wrapper for running valgrind on mesos-master before it is
+# installed that first sets up some flags via environment variables.
+
+# Use colors for errors.
+. @abs_top_srcdir@/support/colors.sh
+
+# Default valgrind tool is "memcheck".
+VALGRINDTOOL=memcheck
+
+# For supplying alternative tools (e.g. "helgrind"), use the -t option.
+while getopts ":t:" opt
+do
+ case "${opt}" in
+ t) VALGRINDTOOL=${OPTARG}; shift 2
+ ;;
+ esac
+done
+
+LIBTOOL=@abs_top_builddir@/libtool
+
+test ! -e ${LIBTOOL} && \
+ echo "${RED}Failed to find ${LIBTOOL}, have you run configure?${NORMAL}" \
+ && exit 1
+
+# Confirm libtool has "valgrind" support.
+${LIBTOOL} --mode=execute valgrind --version >/dev/null 2>&1
+
+test $? != 0 && \
+ echo "${RED}Generated libtool doesn't appear to support valgrind${NORMAL}" \
+ && exit 1
+
+. @abs_top_builddir@/bin/mesos-master-flags.sh
+
+exec ${LIBTOOL} --mode=execute valgrind --tool=${VALGRINDTOOL} \
+ @abs_top_builddir@/src/mesos-master "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/36c7a4d7/bin/valgrind-mesos-slave.sh.in
----------------------------------------------------------------------
diff --git a/bin/valgrind-mesos-slave.sh.in b/bin/valgrind-mesos-slave.sh.in
new file mode 100644
index 0000000..900c588
--- /dev/null
+++ b/bin/valgrind-mesos-slave.sh.in
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+# 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.
+
+# This is a wrapper for running valgrind on mesos-slave before it is
+# installed that first sets up some flags via environment variables.
+
+# Use colors for errors.
+. @abs_top_srcdir@/support/colors.sh
+
+# Default valgrind tool is "memcheck".
+VALGRINDTOOL=memcheck
+
+# For supplying alternative tools (e.g. "helgrind"), use the -t option.
+while getopts ":t:" opt
+do
+ case "${opt}" in
+ t) VALGRINDTOOL=${OPTARG}; shift 2
+ ;;
+ esac
+done
+
+LIBTOOL=@abs_top_builddir@/libtool
+
+test ! -e ${LIBTOOL} && \
+ echo "${RED}Failed to find ${LIBTOOL}, have you run configure?${NORMAL}" \
+ && exit 1
+
+# Confirm libtool has "valgrind" support.
+${LIBTOOL} --mode=execute valgrind --version >/dev/null 2>&1
+
+test $? != 0 && \
+ echo "${RED}Generated libtool doesn't appear to support valgrind${NORMAL}" \
+ && exit 1
+
+. @abs_top_builddir@/bin/mesos-slave-flags.sh
+
+exec ${LIBTOOL} --mode=execute valgrind --tool=${VALGRINDTOOL} \
+ @abs_top_builddir@/src/mesos-slave "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/36c7a4d7/bin/valgrind-mesos-tests.sh.in
----------------------------------------------------------------------
diff --git a/bin/valgrind-mesos-tests.sh.in b/bin/valgrind-mesos-tests.sh.in
new file mode 100644
index 0000000..9adedef
--- /dev/null
+++ b/bin/valgrind-mesos-tests.sh.in
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+# 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.
+
+# This is a wrapper for running valgrind on mesos-tests before it is
+# installed that first sets up some flags via environment variables.
+
+# Use colors for errors.
+. @abs_top_srcdir@/support/colors.sh
+
+# Default valgrind tool is "memcheck".
+VALGRINDTOOL=memcheck
+
+# For supplying alternative tools (e.g. "helgrind"), use the -t option.
+while getopts ":t:" opt
+do
+ case "${opt}" in
+ t) VALGRINDTOOL=${OPTARG}; shift 2
+ ;;
+ esac
+done
+
+LIBTOOL=@abs_top_builddir@/libtool
+
+test ! -e ${LIBTOOL} && \
+ echo "${RED}Failed to find ${LIBTOOL}, have you run configure?${NORMAL}" \
+ && exit 1
+
+# Confirm libtool has "valgrind" support.
+${LIBTOOL} --mode=execute valgrind --version >/dev/null 2>&1
+
+test $? != 0 && \
+ echo "${RED}Generated libtool doesn't appear to support valgrind${NORMAL}" \
+ && exit 1
+
+. @abs_top_builddir@/bin/mesos-tests-flags.sh
+
+exec ${LIBTOOL} --mode=execute valgrind --tool=${VALGRINDTOOL} \
+ @abs_top_builddir@/src/mesos-tests "${@}"
http://git-wip-us.apache.org/repos/asf/mesos/blob/36c7a4d7/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index c21e681..a8bc8a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,10 +95,18 @@ AC_CONFIG_FILES([bin/gdb-mesos-master.sh], [chmod +x bin/gdb-mesos-master.sh])
AC_CONFIG_FILES([bin/gdb-mesos-slave.sh], [chmod +x bin/gdb-mesos-slave.sh])
AC_CONFIG_FILES([bin/gdb-mesos-tests.sh], [chmod +x bin/gdb-mesos-tests.sh])
AC_CONFIG_FILES([bin/lldb-mesos-local.sh], [chmod +x bin/lldb-mesos-local.sh])
-AC_CONFIG_FILES([bin/lldb-mesos-master.sh], [chmod +x bin/lldb-mesos-master.sh])
+AC_CONFIG_FILES([bin/lldb-mesos-master.sh],
+ [chmod +x bin/lldb-mesos-master.sh])
AC_CONFIG_FILES([bin/lldb-mesos-slave.sh], [chmod +x bin/lldb-mesos-slave.sh])
AC_CONFIG_FILES([bin/lldb-mesos-tests.sh], [chmod +x bin/lldb-mesos-tests.sh])
-
+AC_CONFIG_FILES([bin/valgrind-mesos-local.sh],
+ [chmod +x bin/valgrind-mesos-local.sh])
+AC_CONFIG_FILES([bin/valgrind-mesos-slave.sh],
+ [chmod +x bin/valgrind-mesos-slave.sh])
+AC_CONFIG_FILES([bin/valgrind-mesos-master.sh],
+ [chmod +x bin/valgrind-mesos-master.sh])
+AC_CONFIG_FILES([bin/valgrind-mesos-tests.sh],
+ [chmod +x bin/valgrind-mesos-tests.sh])
AC_CONFIG_FILES([src/deploy/mesos-daemon.sh])
AC_CONFIG_FILES([src/deploy/mesos-start-cluster.sh])
AC_CONFIG_FILES([src/deploy/mesos-start-masters.sh])
[3/4] git commit: Added a log tool that does performance tests on the
log.
Posted by vi...@apache.org.
Added a log tool that does performance tests on the log.
Review: https://reviews.apache.org/r/17767
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5c2f4f70
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5c2f4f70
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5c2f4f70
Branch: refs/heads/master
Commit: 5c2f4f7040076de51a5ca7182ac777093bb8aa70
Parents: e15bbe0
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Feb 14 17:05:40 2014 -0800
Committer: Vinod Kone <vi...@twitter.com>
Committed: Fri Feb 14 17:05:40 2014 -0800
----------------------------------------------------------------------
src/Makefile.am | 2 +
src/log/main.cpp | 2 +
src/log/tool/benchmark.cpp | 266 ++++++++++++++++++++++++++++++++++++++++
src/log/tool/benchmark.hpp | 68 ++++++++++
4 files changed, 338 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5c2f4f70/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index dc9042a..cfd7416 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -311,6 +311,7 @@ liblog_la_SOURCES = \
log/log.cpp \
log/recover.cpp \
log/replica.cpp \
+ log/tool/benchmark.cpp \
log/tool/initialize.cpp \
log/tool/read.cpp \
log/tool/replica.cpp
@@ -325,6 +326,7 @@ liblog_la_SOURCES += \
log/replica.hpp \
log/storage.hpp \
log/tool.hpp \
+ log/tool/benchmark.hpp \
log/tool/initialize.hpp \
log/tool/read.hpp \
log/tool/replica.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/5c2f4f70/src/log/main.cpp
----------------------------------------------------------------------
diff --git a/src/log/main.cpp b/src/log/main.cpp
index 2b30fd0..348e887 100644
--- a/src/log/main.cpp
+++ b/src/log/main.cpp
@@ -27,6 +27,7 @@
#include <stout/hashmap.hpp>
#include "log/tool.hpp"
+#include "log/tool/benchmark.hpp"
#include "log/tool/initialize.hpp"
#include "log/tool/read.hpp"
#include "log/tool/replica.hpp"
@@ -68,6 +69,7 @@ static void usage(const char* argv0)
int main(int argc, char** argv)
{
// Register log tools.
+ add(Owned<tool::Tool>(new tool::Benchmark()));
add(Owned<tool::Tool>(new tool::Initialize()));
add(Owned<tool::Tool>(new tool::Read()));
add(Owned<tool::Tool>(new tool::Replica()));
http://git-wip-us.apache.org/repos/asf/mesos/blob/5c2f4f70/src/log/tool/benchmark.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/benchmark.cpp b/src/log/tool/benchmark.cpp
new file mode 100644
index 0000000..7d5a032
--- /dev/null
+++ b/src/log/tool/benchmark.cpp
@@ -0,0 +1,266 @@
+/**
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <process/clock.hpp>
+#include <process/process.hpp>
+#include <process/time.hpp>
+
+#include <stout/bytes.hpp>
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/stopwatch.hpp>
+#include <stout/strings.hpp>
+#include <stout/os/read.hpp>
+
+#include "log/log.hpp"
+#include "log/tool/initialize.hpp"
+#include "log/tool/benchmark.hpp"
+
+#include "logging/logging.hpp"
+
+using namespace process;
+
+using std::cout;
+using std::endl;
+using std::ifstream;
+using std::ofstream;
+using std::ostringstream;
+using std::string;
+using std::vector;
+
+namespace mesos {
+namespace internal {
+namespace log {
+namespace tool {
+
+Benchmark::Flags::Flags()
+{
+ add(&Flags::quorum,
+ "quorum",
+ "Quorum size");
+
+ add(&Flags::path,
+ "path",
+ "Path to the log");
+
+ add(&Flags::servers,
+ "servers",
+ "ZooKeeper servers");
+
+ add(&Flags::znode,
+ "znode",
+ "ZooKeeper znode");
+
+ add(&Flags::input,
+ "input",
+ "Path to the input trace file. Each line in the trace file\n"
+ "specifies the size of the append (e.g. 100B, 2MB, etc.)");
+
+ add(&Flags::output,
+ "output",
+ "Path to the output file");
+
+ add(&Flags::type,
+ "type",
+ "Type of data to be written (zero, one, random)\n"
+ " zero: all bits are 0\n"
+ " one: all bits are 1\n"
+ " random: all bits are randomly chosen\n",
+ "random");
+
+ add(&Flags::initialize,
+ "initialize",
+ "Whether to initialize the log",
+ true);
+
+ add(&Flags::help,
+ "help",
+ "Prints the help message",
+ false);
+}
+
+
+string Benchmark::usage(const string& argv0) const
+{
+ ostringstream out;
+
+ out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
+ << endl
+ << "This command is used to do performance test on the" << endl
+ << "replicated log. It takes a trace file of write sizes" << endl
+ << "and replay that trace to measure the latency of each" << endl
+ << "write. The data to be written for each write can be" << endl
+ << "specified using the '--type' flag." << endl
+ << endl
+ << "Supported OPTIONS:" << endl
+ << flags.usage();
+
+ return out.str();
+}
+
+
+Try<Nothing> Benchmark::execute(int argc, char** argv)
+{
+ // Configure the tool by parsing command line arguments.
+ if (argc > 0 && argv != NULL) {
+ Try<Nothing> load = flags.load(None(), argc, argv);
+ if (load.isError()) {
+ return Error(load.error() + "\n\n" + usage(argv[0]));
+ }
+
+ if (flags.help) {
+ return Error(usage(argv[0]));
+ }
+
+ process::initialize();
+ logging::initialize(argv[0], flags);
+ }
+
+ if (flags.quorum.isNone()) {
+ return Error("Missing flag '--quorum'");
+ }
+
+ if (flags.path.isNone()) {
+ return Error("Missing flag '--path'");
+ }
+
+ if (flags.servers.isNone()) {
+ return Error("Missing flag '--servers'");
+ }
+
+ if (flags.znode.isNone()) {
+ return Error("Missing flag '--znode'");
+ }
+
+ if (flags.input.isNone()) {
+ return Error("Missing flag '--input'");
+ }
+
+ if (flags.output.isNone()) {
+ return Error("Missing flag '--output'");
+ }
+
+ // Initialize the log.
+ if (flags.initialize) {
+ Initialize initialize;
+ initialize.flags.path = flags.path;
+
+ Try<Nothing> execution = initialize.execute();
+ if (execution.isError()) {
+ return Error(execution.error());
+ }
+ }
+
+ // Create the log.
+ Log log(
+ flags.quorum.get(),
+ flags.path.get(),
+ flags.servers.get(),
+ Seconds(10),
+ flags.znode.get());
+
+ // Create the log writer.
+ Log::Writer writer(&log, Seconds(15), 20);
+
+ // Statistics to output.
+ vector<Bytes> sizes;
+ vector<Duration> durations;
+ vector<Time> timestamps;
+
+ // Read sizes from the input trace file.
+ ifstream input(flags.input.get().c_str());
+ if (!input.is_open()) {
+ return Error("Failed to open the trace file " + flags.input.get());
+ }
+
+ string line;
+ while (getline(input, line)) {
+ Try<Bytes> size = Bytes::parse(strings::trim(line));
+ if (size.isError()) {
+ input.close();
+ return Error("Failed to parse the trace file: " + size.error());
+ }
+
+ sizes.push_back(size.get());
+ }
+
+ input.close();
+
+ // Generate the data to be written.
+ vector<string> data;
+ for (size_t i = 0; i < sizes.size(); i++) {
+ if (flags.type == "one") {
+ data.push_back(string(sizes[i].bytes(), 255));
+ } else if (flags.type == "random") {
+ data.push_back(string(sizes[i].bytes(), ::random() % 256));
+ } else {
+ data.push_back(string(sizes[i].bytes(), 0));
+ }
+ }
+
+ Stopwatch stopwatch;
+ stopwatch.start();
+
+ for (size_t i = 0; i < sizes.size(); i++) {
+ Stopwatch stopwatch;
+ stopwatch.start();
+
+ Result<Log::Position> position =
+ writer.append(data[i], Timeout::in(Seconds(10)));
+
+ if (position.isError()) {
+ return Error("Failed to append: " + position.error());
+ } else if (position.isNone()) {
+ return Error("Timed out while appending");
+ }
+
+ durations.push_back(stopwatch.elapsed());
+ timestamps.push_back(Clock::now());
+ }
+
+ cout << "Total number of appends: " << sizes.size() << endl;
+ cout << "Total time used: " << stopwatch.elapsed() << endl;
+
+ // Ouput statistics.
+ ofstream output(flags.output.get().c_str());
+ if (!output.is_open()) {
+ return Error("Failed to open the output file " + flags.output.get());
+ }
+
+ for (size_t i = 0; i < sizes.size(); i++) {
+ output << timestamps[i]
+ << " Appended " << sizes[i].bytes() << " bytes"
+ << " in " << durations[i].ms() << " ms" << endl;
+ }
+
+ output.close();
+
+ return Nothing();
+}
+
+} // namespace tool {
+} // namespace log {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/5c2f4f70/src/log/tool/benchmark.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/benchmark.hpp b/src/log/tool/benchmark.hpp
new file mode 100644
index 0000000..e0109e2
--- /dev/null
+++ b/src/log/tool/benchmark.hpp
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+
+#ifndef __LOG_TOOL_BENCHMARK_HPP__
+#define __LOG_TOOL_BENCHMARK_HPP__
+
+#include <stout/flags.hpp>
+#include <stout/option.hpp>
+
+#include "log/tool.hpp"
+
+#include "logging/flags.hpp"
+
+namespace mesos {
+namespace internal {
+namespace log {
+namespace tool {
+
+class Benchmark : public Tool
+{
+public:
+ class Flags : public logging::Flags
+ {
+ public:
+ Flags();
+
+ Option<size_t> quorum;
+ Option<std::string> path;
+ Option<std::string> servers;
+ Option<std::string> znode;
+ Option<std::string> input;
+ Option<std::string> output;
+ std::string type;
+ bool initialize;
+ bool help;
+ };
+
+ virtual std::string name() const { return "benchmark"; }
+ virtual Try<Nothing> execute(int argc = 0, char** argv = NULL);
+
+ // Users can change the default configuration by setting this flags.
+ Flags flags;
+
+private:
+ std::string usage(const std::string& argv0) const;
+};
+
+} // namespace tool {
+} // namespace log {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __LOG_TOOL_BENCHMARK_HPP__
[4/4] git commit: Added observe endpoint to master.
Posted by vi...@apache.org.
Added observe endpoint to master.
This changes adds a new HTTP endpoint of observe to master.
This allows clients to report health via an HTTP POST.
Values are:
MONITOR = Monitor for which health is being reported.
HOSTS = Comma seperated list of hosts.
LEVEL = OK for healthy, anything else for unhealthy.
This also contains a small fix to alphabetize the existing
endpoints / help strings.
Review: https://reviews.apache.org/r/17255
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/165dbe10
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/165dbe10
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/165dbe10
Branch: refs/heads/master
Commit: 165dbe101812f50780a802c8eea0dd5579678d96
Parents: 5c2f4f7
Author: Charlie Carson <ch...@gmail.com>
Authored: Fri Feb 14 17:07:35 2014 -0800
Committer: Vinod Kone <vi...@twitter.com>
Committed: Fri Feb 14 17:07:35 2014 -0800
----------------------------------------------------------------------
src/Makefile.am | 1 +
src/master/http.cpp | 99 ++++++++++++++++++++++
src/master/master.cpp | 9 +-
src/master/master.hpp | 13 ++-
src/tests/repair_tests.cpp | 176 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 291 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/165dbe10/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index cfd7416..768c66a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -870,6 +870,7 @@ mesos_tests_SOURCES = \
tests/paths_tests.cpp \
tests/protobuf_io_tests.cpp \
tests/registrar_tests.cpp \
+ tests/repair_tests.cpp \
tests/resource_offers_tests.cpp \
tests/resources_tests.cpp \
tests/sasl_tests.cpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/165dbe10/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 966eed6..6aeb257 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -22,6 +22,8 @@
#include <string>
#include <vector>
+#include <boost/array.hpp>
+
#include <mesos/mesos.hpp>
#include <mesos/resources.hpp>
@@ -278,6 +280,103 @@ Future<Response> Master::Http::health(const Request& request)
return OK();
}
+const static string HOSTS_KEY = "hosts";
+const static string LEVEL_KEY = "level";
+const static string MONITOR_KEY = "monitor";
+
+const string Master::Http::OBSERVE_HELP = HELP(
+ TLDR(
+ "Observe a monitor health state for host(s)."),
+ USAGE(
+ "/master/observe"),
+ DESCRIPTION(
+ "This endpoint receives information indicating host(s) ",
+ "health."
+ "",
+ "The following fields should be supplied in a POST:",
+ "1. " + MONITOR_KEY + " - name of the monitor that is being reported",
+ "2. " + HOSTS_KEY + " - comma seperated list of hosts",
+ "3. " + LEVEL_KEY + " - OK for healthy, anything else for unhealthy"));
+
+
+Try<string> getFormValue(
+ const string& key,
+ const hashmap<string, string>& values)
+{
+ Option<string> value = values.get(key);
+
+ if (value.isNone()) {
+ return Error("Missing value for '" + key + "'.");
+ }
+
+ // HTTP decode the value.
+ Try<string> decodedValue = http::decode(value.get());
+ if (decodedValue.isError()) {
+ return decodedValue;
+ }
+
+ // Treat empty string as an error.
+ if (decodedValue.isSome() && decodedValue.get().empty()) {
+ return Error("Empty string for '" + key + "'.");
+ }
+
+ return decodedValue.get();
+}
+
+
+Future<Response> Master::Http::observe(const Request& request)
+{
+ LOG(INFO) << "HTTP request for '" << request.path << "'";
+
+ hashmap<string, string> values =
+ process::http::query::parse(request.body);
+
+ // Build up a JSON object of the values we recieved and send them back
+ // down the wire as JSON for validation / confirmation.
+ JSON::Object response;
+
+ // TODO(ccarson): As soon as RepairCoordinator is introduced it will
+ // consume these values. We should revisit if we still want to send the
+ // JSON down the wire at that point.
+
+ // Add 'monitor'.
+ Try<string> monitor = getFormValue(MONITOR_KEY, values);
+ if (monitor.isError()) {
+ return BadRequest(monitor.error());
+ }
+ response.values[MONITOR_KEY] = monitor.get();
+
+ // Add 'hosts'.
+ Try<string> hostsString = getFormValue(HOSTS_KEY, values);
+ if (hostsString.isError()) {
+ return BadRequest(hostsString.error());
+ }
+
+ vector<string> hosts = strings::split(hostsString.get(), ",");
+ JSON::Array hostArray;
+ hostArray.values.assign(hosts.begin(), hosts.end());
+
+ response.values[HOSTS_KEY] = hostArray;
+
+ // Add 'isHealthy'.
+ Try<string> level = getFormValue(LEVEL_KEY, values);
+ if (level.isError()) {
+ return BadRequest(level.error());
+ }
+
+ bool isHealthy = strings::upper(level.get()) == "OK";
+
+ // TODO(ccarson): This is a workaround b/c currently a bool is coerced
+ // into a JSON::Double instead of a JSON::True or JSON::False when
+ // you assign to a JSON::Value.
+ //
+ // SEE: https://issues.apache.org/jira/browse/MESOS-939
+ response.values["isHealthy"] =
+ (isHealthy ? JSON::Value(JSON::True()) : JSON::False());
+
+ return OK(response);
+}
+
const string Master::Http::REDIRECT_HELP = HELP(
TLDR(
http://git-wip-us.apache.org/repos/asf/mesos/blob/165dbe10/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index f24df23..f4f5e04 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -462,16 +462,19 @@ void Master::initialize()
route("/health",
Http::HEALTH_HELP,
lambda::bind(&Http::health, http, lambda::_1));
+ route("/observe",
+ Http::OBSERVE_HELP,
+ lambda::bind(&Http::observe, http, lambda::_1));
route("/redirect",
Http::REDIRECT_HELP,
lambda::bind(&Http::redirect, http, lambda::_1));
- route("/stats.json",
+ route("/roles.json",
None(),
- lambda::bind(&Http::stats, http, lambda::_1));
+ lambda::bind(&Http::roles, http, lambda::_1));
route("/state.json",
None(),
lambda::bind(&Http::state, http, lambda::_1));
- route("/roles.json",
+ route("/stats.json",
None(),
lambda::bind(&Http::roles, http, lambda::_1));
http://git-wip-us.apache.org/repos/asf/mesos/blob/165dbe10/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 00d630a..9d1b56c 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -280,20 +280,24 @@ private:
process::Future<process::http::Response> health(
const process::http::Request& request);
+ // /master/observe
+ process::Future<process::http::Response> observe(
+ const process::http::Request& request);
+
// /master/redirect
process::Future<process::http::Response> redirect(
const process::http::Request& request);
- // /master/stats.json
- process::Future<process::http::Response> stats(
+ // /master/roles.json
+ process::Future<process::http::Response> roles(
const process::http::Request& request);
// /master/state.json
process::Future<process::http::Response> state(
const process::http::Request& request);
- // /master/roles.json
- process::Future<process::http::Response> roles(
+ // /master/stats.json
+ process::Future<process::http::Response> stats(
const process::http::Request& request);
// /master/tasks.json
@@ -301,6 +305,7 @@ private:
const process::http::Request& request);
const static std::string HEALTH_HELP;
+ const static std::string OBSERVE_HELP;
const static std::string REDIRECT_HELP;
const static std::string TASKS_HELP;
http://git-wip-us.apache.org/repos/asf/mesos/blob/165dbe10/src/tests/repair_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/repair_tests.cpp b/src/tests/repair_tests.cpp
new file mode 100644
index 0000000..ba6f50a
--- /dev/null
+++ b/src/tests/repair_tests.cpp
@@ -0,0 +1,176 @@
+/**
+ * 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 <string>
+#include <vector>
+
+#include <process/future.hpp>
+#include <process/gtest.hpp>
+#include <process/http.hpp>
+#include <process/pid.hpp>
+#include <process/process.hpp>
+
+#include <stout/json.hpp>
+
+#include "tests/mesos.hpp"
+
+
+using namespace mesos;
+using namespace mesos::internal;
+using namespace mesos::internal::tests;
+
+using mesos::internal::master::Master;
+
+using process::Future;
+using process::PID;
+
+using process::http::BadRequest;
+using process::http::OK;
+using process::http::Response;
+
+using std::string;
+using std::vector;
+
+using testing::_;
+
+
+class HealthTest : public MesosTest {};
+
+
+struct JsonResponse
+{
+ string monitor;
+ vector<string> hosts;
+ bool isHealthy;
+};
+
+
+string stringify(const JsonResponse& response)
+{
+ JSON::Object object;
+ object.values["monitor"] = response.monitor;
+
+ JSON::Array hosts;
+ hosts.values.assign(response.hosts.begin(), response.hosts.end());
+ object.values["hosts"] = hosts;
+
+ // TODO(ccarson): This is a workaround b/c currently a bool is coerced
+ // into a JSON::Double instead of a JSON::True or JSON::False when
+ // you assign to a JSON::Value.
+ //
+ // SEE: https://issues.apache.org/jira/browse/MESOS-939
+ object.values["isHealthy"] =
+ response.isHealthy ? JSON::Value(JSON::True()) : JSON::False();
+
+ return stringify(object);
+}
+
+
+// Using macros instead of a helper function so that we get good line
+// numbers from the test run.
+#define VALIDATE_BAD_RESPONSE(response, error) \
+ AWAIT_READY(response); \
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); \
+ AWAIT_EXPECT_RESPONSE_BODY_EQ(error, response)
+
+#define VALIDATE_GOOD_RESPONSE(response, jsonResponse) \
+ AWAIT_READY(response); \
+ AWAIT_EXPECT_RESPONSE_HEADER_EQ( \
+ "application/json", \
+ "Content-Type", \
+ response); \
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); \
+ AWAIT_EXPECT_RESPONSE_BODY_EQ(jsonResponse, response);
+
+
+TEST_F(HealthTest, ObserveEndpoint)
+{
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ // Empty get to the observe endpoint.
+ Future<Response> response = process::http::get(master.get(), "observe");
+ VALIDATE_BAD_RESPONSE(response, "Missing value for 'monitor'.");
+
+ // Empty post to the observe endpoint.
+ response = process::http::post(master.get(), "observe");
+ VALIDATE_BAD_RESPONSE(response, "Missing value for 'monitor'.");
+
+ // Query string is ignored.
+ response = process::http::post(master.get(), "observe?monitor=foo");
+ VALIDATE_BAD_RESPONSE(response, "Missing value for 'monitor'.");
+
+ // Malformed value causes error.
+ response = process::http::post(master.get(), "observe", "monitor=foo%");
+ VALIDATE_BAD_RESPONSE(response, "Malformed % escape in 'foo%': '%'");
+
+ // Empty value causes error.
+ response = process::http::post(master.get(), "observe", "monitor=");
+ VALIDATE_BAD_RESPONSE(response, "Empty string for 'monitor'.");
+
+ // Missing hosts.
+ response = process::http::post(master.get(), "observe", "monitor=a");
+ VALIDATE_BAD_RESPONSE(response, "Missing value for 'hosts'.");
+
+ // Missing level.
+ response = process::http::post(master.get(), "observe", "monitor=a&hosts=b");
+ VALIDATE_BAD_RESPONSE(response, "Missing value for 'level'.");
+
+ // Good request is successful.
+ JsonResponse expected;
+ expected.monitor = "a";
+ expected.hosts.push_back("b");
+ expected.isHealthy = true;
+
+ response =
+ process::http::post(master.get(), "observe", "monitor=a&hosts=b&level=ok");
+ VALIDATE_GOOD_RESPONSE(response, stringify(expected) );
+
+ // ok is case-insensitive.
+ response =
+ process::http::post(master.get(), "observe", "monitor=a&hosts=b&level=Ok");
+ VALIDATE_GOOD_RESPONSE(response, stringify(expected) );
+
+ response =
+ process::http::post(master.get(), "observe", "monitor=a&hosts=b&level=oK");
+ VALIDATE_GOOD_RESPONSE(response, stringify(expected) );
+
+ response =
+ process::http::post(master.get(), "observe", "monitor=a&hosts=b&level=OK");
+ VALIDATE_GOOD_RESPONSE(response, stringify(expected) );
+
+ // level != OK is unhealthy.
+ expected.isHealthy = false;
+ response =
+ process::http::post(
+ master.get(),
+ "observe",
+ "monitor=a&hosts=b&level=true");
+ VALIDATE_GOOD_RESPONSE(response, stringify(expected) );
+
+ // Comma seperated hosts are parsed into an array.
+ expected.hosts.push_back("e");
+ response =
+ process::http::post(
+ master.get(),
+ "observe",
+ "monitor=a&hosts=b,e&level=true");
+ VALIDATE_GOOD_RESPONSE(response, stringify(expected) );
+
+ Shutdown();
+}
[2/4] git commit: Added a log tool to start a replica server.
Posted by vi...@apache.org.
Added a log tool to start a replica server.
Review: https://reviews.apache.org/r/17755
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e15bbe0f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e15bbe0f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e15bbe0f
Branch: refs/heads/master
Commit: e15bbe0fd9c46109b72e11f5e6eb06a5b67294c5
Parents: 36c7a4d
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Feb 14 17:05:26 2014 -0800
Committer: Vinod Kone <vi...@twitter.com>
Committed: Fri Feb 14 17:05:26 2014 -0800
----------------------------------------------------------------------
src/Makefile.am | 4 +-
src/log/main.cpp | 2 +
src/log/tool/replica.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++
src/log/tool/replica.hpp | 66 +++++++++++++++++++
4 files changed, 221 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/e15bbe0f/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 9a33f21..dc9042a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -312,7 +312,8 @@ liblog_la_SOURCES = \
log/recover.cpp \
log/replica.cpp \
log/tool/initialize.cpp \
- log/tool/read.cpp
+ log/tool/read.cpp \
+ log/tool/replica.cpp
liblog_la_SOURCES += \
log/catchup.hpp \
log/consensus.hpp \
@@ -326,6 +327,7 @@ liblog_la_SOURCES += \
log/tool.hpp \
log/tool/initialize.hpp \
log/tool/read.hpp \
+ log/tool/replica.hpp \
messages/log.hpp \
messages/log.proto
nodist_liblog_la_SOURCES = $(LOG_PROTOS)
http://git-wip-us.apache.org/repos/asf/mesos/blob/e15bbe0f/src/log/main.cpp
----------------------------------------------------------------------
diff --git a/src/log/main.cpp b/src/log/main.cpp
index c37dd6f..2b30fd0 100644
--- a/src/log/main.cpp
+++ b/src/log/main.cpp
@@ -29,6 +29,7 @@
#include "log/tool.hpp"
#include "log/tool/initialize.hpp"
#include "log/tool/read.hpp"
+#include "log/tool/replica.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -69,6 +70,7 @@ int main(int argc, char** argv)
// Register log tools.
add(Owned<tool::Tool>(new tool::Initialize()));
add(Owned<tool::Tool>(new tool::Read()));
+ add(Owned<tool::Tool>(new tool::Replica()));
if (argc < 2) {
usage(argv[0]);
http://git-wip-us.apache.org/repos/asf/mesos/blob/e15bbe0f/src/log/tool/replica.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/replica.cpp b/src/log/tool/replica.cpp
new file mode 100644
index 0000000..3985fc7
--- /dev/null
+++ b/src/log/tool/replica.cpp
@@ -0,0 +1,150 @@
+/**
+ * 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 <iostream>
+#include <sstream>
+
+#include <process/future.hpp>
+#include <process/process.hpp>
+
+#include <stout/error.hpp>
+
+#include "log/log.hpp"
+#include "log/tool/initialize.hpp"
+#include "log/tool/replica.hpp"
+
+#include "logging/logging.hpp"
+
+using namespace process;
+
+using std::endl;
+using std::ostringstream;
+using std::string;
+
+namespace mesos {
+namespace internal {
+namespace log {
+namespace tool {
+
+Replica::Flags::Flags()
+{
+ add(&Flags::quorum,
+ "quorum",
+ "Quorum size");
+
+ add(&Flags::path,
+ "path",
+ "Path to the log");
+
+ add(&Flags::servers,
+ "servers",
+ "ZooKeeper servers");
+
+ add(&Flags::znode,
+ "znode",
+ "ZooKeeper znode");
+
+ add(&Flags::initialize,
+ "initialize",
+ "Whether to initialize the log",
+ true);
+
+ add(&Flags::help,
+ "help",
+ "Prints the help message",
+ false);
+}
+
+
+string Replica::usage(const string& argv0) const
+{
+ ostringstream out;
+
+ out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
+ << endl
+ << "This command is used to start a replica server" << endl
+ << endl
+ << "Supported OPTIONS:" << endl
+ << flags.usage();
+
+ return out.str();
+}
+
+
+Try<Nothing> Replica::execute(int argc, char** argv)
+{
+ // Configure the tool by parsing command line arguments.
+ if (argc > 0 && argv != NULL) {
+ Try<Nothing> load = flags.load(None(), argc, argv);
+ if (load.isError()) {
+ return Error(load.error() + "\n\n" + usage(argv[0]));
+ }
+
+ if (flags.help) {
+ return Error(usage(argv[0]));
+ }
+
+ process::initialize();
+ logging::initialize(argv[0], flags);
+ }
+
+ if (flags.quorum.isNone()) {
+ return Error("Missing flag '--quorum'");
+ }
+
+ if (flags.path.isNone()) {
+ return Error("Missing flag '--path'");
+ }
+
+ if (flags.servers.isNone()) {
+ return Error("Missing flag '--servers'");
+ }
+
+ if (flags.znode.isNone()) {
+ return Error("Missing flag '--znode'");
+ }
+
+ // Initialize the log.
+ if (flags.initialize) {
+ Initialize initialize;
+ initialize.flags.path = flags.path;
+
+ Try<Nothing> execution = initialize.execute();
+ if (execution.isError()) {
+ return Error(execution.error());
+ }
+ }
+
+ // Create the log.
+ Log log(
+ flags.quorum.get(),
+ flags.path.get(),
+ flags.servers.get(),
+ Seconds(10),
+ flags.znode.get());
+
+ // Loop forever.
+ Future<Nothing>().get();
+
+ return Nothing();
+}
+
+} // namespace tool {
+} // namespace log {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/e15bbe0f/src/log/tool/replica.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/replica.hpp b/src/log/tool/replica.hpp
new file mode 100644
index 0000000..b433348
--- /dev/null
+++ b/src/log/tool/replica.hpp
@@ -0,0 +1,66 @@
+/**
+ * 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.
+ */
+
+#ifndef __LOG_TOOL_REPLICA_HPP__
+#define __LOG_TOOL_REPLICA_HPP__
+
+#include <stout/flags.hpp>
+#include <stout/option.hpp>
+
+#include "log/tool.hpp"
+
+#include "logging/flags.hpp"
+
+namespace mesos {
+namespace internal {
+namespace log {
+namespace tool {
+
+// Start a replica server.
+class Replica : public Tool
+{
+public:
+ class Flags : public logging::Flags
+ {
+ public:
+ Flags();
+
+ Option<size_t> quorum;
+ Option<std::string> path;
+ Option<std::string> servers;
+ Option<std::string> znode;
+ bool initialize;
+ bool help;
+ };
+
+ virtual std::string name() const { return "replica"; }
+ virtual Try<Nothing> execute(int argc = 0, char** argv = NULL);
+
+ // Users can change the default configuration by setting this flags.
+ Flags flags;
+
+private:
+ std::string usage(const std::string& argv0) const;
+};
+
+} // namespace tool {
+} // namespace log {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __LOG_TOOL_REPLICA_HPP__