You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2012/03/27 08:03:47 UTC
svn commit: r1305740 - in /incubator/mesos/trunk: include/mesos/ src/common/
src/examples/ src/examples/java/ src/launcher/ src/slave/
Author: benh
Date: Tue Mar 27 06:03:46 2012
New Revision: 1305740
URL: http://svn.apache.org/viewvc?rev=1305740&view=rev
Log:
CommandInfo now accepts list of URIs (contributed by Vinod Kone).
Modified:
incubator/mesos/trunk/include/mesos/mesos.proto
incubator/mesos/trunk/src/common/type_utils.hpp
incubator/mesos/trunk/src/examples/java/TestFramework.java
incubator/mesos/trunk/src/examples/java/TestMultipleExecutorsFramework.java
incubator/mesos/trunk/src/examples/long_lived_framework.cpp
incubator/mesos/trunk/src/examples/test_framework.cpp
incubator/mesos/trunk/src/launcher/launcher.cpp
incubator/mesos/trunk/src/launcher/launcher.hpp
incubator/mesos/trunk/src/launcher/main.cpp
incubator/mesos/trunk/src/slave/http.cpp
incubator/mesos/trunk/src/slave/lxc_isolation_module.cpp
incubator/mesos/trunk/src/slave/process_based_isolation_module.cpp
Modified: incubator/mesos/trunk/include/mesos/mesos.proto
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/include/mesos/mesos.proto?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/include/mesos/mesos.proto (original)
+++ incubator/mesos/trunk/include/mesos/mesos.proto Tue Mar 27 06:03:46 2012
@@ -93,12 +93,20 @@ message FrameworkInfo {
/**
* Describes a command, executed via: '/bin/sh -c value'. Any uri's
- * specified are fetched before executing the command. In addition,
- * any environment variables are set before executing the command (so
- * they can be used to "parameterize" your command).
+ * specified are fetched before executing the command.
+ * If executable field for an uri is set, executable file permission
+ * is set on the downloaded file. Also, if the downloaded file has ".tgz"
+ * extension it is extracted into the executor's working directory.
+ * In addition, any environment variables are set before executing
+ * the command (so they can be used to "parameterize" your command).
*/
message CommandInfo {
- optional string uri = 1; // TODO(benh): Make this repeated.
+ message URI {
+ required string value = 1;
+ optional bool executable = 2;
+ }
+
+ repeated URI uris = 1;
optional Environment environment = 2;
required string value = 3;
}
Modified: incubator/mesos/trunk/src/common/type_utils.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/common/type_utils.hpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/common/type_utils.hpp (original)
+++ incubator/mesos/trunk/src/common/type_utils.hpp Tue Mar 27 06:03:46 2012
@@ -187,6 +187,7 @@ inline bool operator == (const Environme
if (name == right.variables().Get(j).name() &&
value == right.variables().Get(j).value()) {
found = true;
+ break;
}
}
if (!found) {
@@ -198,11 +199,35 @@ inline bool operator == (const Environme
}
+inline bool operator == (const CommandInfo::URI& left,
+ const CommandInfo::URI& right)
+{
+ return left.has_executable() == right.has_executable() &&
+ (!left.has_executable() || (left.executable() == right.executable())) &&
+ left.value() == right.value();
+}
+
+
inline bool operator == (const CommandInfo& left, const CommandInfo& right)
{
- return left.has_uri() == right.has_uri() &&
- (!left.has_uri() || (left.uri() == right.uri())) &&
- left.has_environment() == right.has_environment() &&
+ if (left.uris().size() != right.uris().size()) {
+ return false;
+ }
+
+ for (int i=0; i<left.uris().size(); i++) {
+ bool found = false;
+ for (int j=0; j<right.uris().size(); j++) {
+ if (left.uris().Get(i) == right.uris().Get(j)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+
+ return left.has_environment() == right.has_environment() &&
(!left.has_environment() || (left.environment() == right.environment())) &&
left.value() == right.value();
}
Modified: incubator/mesos/trunk/src/examples/java/TestFramework.java
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/examples/java/TestFramework.java?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/examples/java/TestFramework.java (original)
+++ incubator/mesos/trunk/src/examples/java/TestFramework.java Tue Mar 27 06:03:46 2012
@@ -133,7 +133,7 @@ public class TestFramework {
ExecutorInfo executor = ExecutorInfo.newBuilder()
.setExecutorId(ExecutorID.newBuilder().setValue("default").build())
- .setCommand(CommandInfo.newBuilder().setUri(uri).setValue(uri).build())
+ .setCommand(CommandInfo.newBuilder().setValue(uri).build())
.build();
MesosSchedulerDriver driver = args.length == 1
Modified: incubator/mesos/trunk/src/examples/java/TestMultipleExecutorsFramework.java
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/examples/java/TestMultipleExecutorsFramework.java?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/examples/java/TestMultipleExecutorsFramework.java (original)
+++ incubator/mesos/trunk/src/examples/java/TestMultipleExecutorsFramework.java Tue Mar 27 06:03:46 2012
@@ -75,7 +75,6 @@ public class TestMultipleExecutorsFramew
.setValue("executor-foo")
.build())
.setCommand(CommandInfo.newBuilder()
- .setUri(file.getCanonicalPath())
.setValue(file.getCanonicalPath())
.build())
.build())
@@ -117,7 +116,6 @@ public class TestMultipleExecutorsFramew
.setValue("executor-bar")
.build())
.setCommand(CommandInfo.newBuilder()
- .setUri(file.getCanonicalPath())
.setValue(file.getCanonicalPath())
.build())
.build())
Modified: incubator/mesos/trunk/src/examples/long_lived_framework.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/examples/long_lived_framework.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/examples/long_lived_framework.cpp (original)
+++ incubator/mesos/trunk/src/examples/long_lived_framework.cpp Tue Mar 27 06:03:46 2012
@@ -156,7 +156,6 @@ int main(int argc, char** argv)
ExecutorInfo executor;
executor.mutable_executor_id()->set_value("default");
- executor.mutable_command()->set_uri(uri);
executor.mutable_command()->set_value(uri);
LongLivedScheduler scheduler(executor);
Modified: incubator/mesos/trunk/src/examples/test_framework.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/examples/test_framework.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/examples/test_framework.cpp (original)
+++ incubator/mesos/trunk/src/examples/test_framework.cpp Tue Mar 27 06:03:46 2012
@@ -168,7 +168,6 @@ int main(int argc, char** argv)
ExecutorInfo executor;
executor.mutable_executor_id()->set_value("default");
- executor.mutable_command()->set_uri(uri);
executor.mutable_command()->set_value(uri);
TestScheduler scheduler(executor);
Modified: incubator/mesos/trunk/src/launcher/launcher.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/launcher/launcher.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/launcher/launcher.cpp (original)
+++ incubator/mesos/trunk/src/launcher/launcher.cpp Tue Mar 27 06:03:46 2012
@@ -47,8 +47,7 @@ namespace launcher {
ExecutorLauncher::ExecutorLauncher(
const FrameworkID& _frameworkId,
const ExecutorID& _executorId,
- const string& _executorUri,
- const string& _command,
+ const CommandInfo& _commandInfo,
const string& _user,
const string& _workDirectory,
const string& _slavePid,
@@ -56,12 +55,10 @@ ExecutorLauncher::ExecutorLauncher(
const string& _hadoopHome,
bool _redirectIO,
bool _shouldSwitchUser,
- const string& _container,
- const Environment& _environment)
+ const string& _container)
: frameworkId(_frameworkId),
executorId(_executorId),
- executorUri(_executorUri),
- command(_command),
+ commandInfo(_commandInfo),
user(_user),
workDirectory(_workDirectory),
slavePid(_slavePid),
@@ -69,8 +66,7 @@ ExecutorLauncher::ExecutorLauncher(
hadoopHome(_hadoopHome),
redirectIO(_redirectIO),
shouldSwitchUser(_shouldSwitchUser),
- container(_container),
- environment(_environment) {}
+ container(_container) {}
ExecutorLauncher::~ExecutorLauncher() {}
@@ -95,7 +91,7 @@ int ExecutorLauncher::run()
}
}
- fetchExecutor(); // TODO(benh): fetchExecutors();
+ fetchExecutors();
setupEnvironment();
@@ -103,6 +99,8 @@ int ExecutorLauncher::run()
switchUser();
}
+ const string& command = commandInfo.value();
+
// TODO(benh): Clean up this gross special cased LXC garbage!!!!
if (container != "") {
// If we are running with a container than we need to fork an
@@ -142,11 +140,13 @@ void ExecutorLauncher::initializeWorking
}
-// Download the executor's binary if required and return its path.
-void ExecutorLauncher::fetchExecutor()
-{
- if (executorUri != "") {
- string executor = executorUri;
+// Download the executor's files and optionally set executable permissions
+// if requested.
+void ExecutorLauncher::fetchExecutors()
+{
+ foreach(const CommandInfo::URI& uri, commandInfo.uris()) {
+ string executor = uri.value();
+ bool executable = uri.has_executable() && uri.executable();
// Some checks to make using the executor in shell commands safe;
// these should be pushed into the master and reported to the user
@@ -182,7 +182,7 @@ void ExecutorLauncher::fetchExecutor()
if (ret != 0)
fatal("HDFS copyToLocal failed: return code %d", ret);
executor = localFile;
- if (chmod(executor.c_str(), S_IRWXU | S_IRGRP | S_IXGRP |
+ if (executable && chmod(executor.c_str(), S_IRWXU | S_IRGRP | S_IXGRP |
S_IROTH | S_IXOTH) != 0)
fatalerror("chmod failed");
} else if (executor.find("http://") == 0
@@ -202,7 +202,7 @@ void ExecutorLauncher::fetchExecutor()
code.get());
}
executor = path;
- if (chmod(executor.c_str(), S_IRWXU | S_IRGRP | S_IXGRP |
+ if (executable && chmod(executor.c_str(), S_IRWXU | S_IRGRP | S_IXGRP |
S_IROTH | S_IXOTH) != 0)
fatalerror("chmod failed");
} else if (executor.find_first_of("/") != 0) {
@@ -219,43 +219,13 @@ void ExecutorLauncher::fetchExecutor()
}
}
- // If the executor was a .tgz, untar it in the work directory. The .tgz
- // expected to contain a single directory. This directory should contain
- // a program or script called "executor" to run the executor. We chdir
- // into this directory and run the script from in there.
+ // If the executor was a .tgz, untar it in the work directory.
if (executor.rfind(".tgz") == executor.size() - strlen(".tgz")) {
string command = "tar xzf '" + executor + "'";
cout << "Untarring executor: " + command << endl;
int ret = system(command.c_str());
if (ret != 0)
fatal("Untar failed: return code %d", ret);
- // The .tgz should have contained a single directory; find it
- if (DIR *dir = opendir(".")) {
- bool found = false;
- string dirname = "";
- while (struct dirent *ent = readdir(dir)) {
- if (string(".") != ent->d_name && string("..") != ent->d_name) {
- struct stat info;
- if (stat(ent->d_name, &info) == 0) {
- if (S_ISDIR(info.st_mode)) {
- if (found) // Already found a directory earlier
- fatal("Executor .tgz must contain a single directory");
- dirname = ent->d_name;
- found = true;
- }
- } else {
- fatalerror("Stat failed on %s", ent->d_name);
- }
- }
- }
- if (!found) // No directory found
- fatal("Executor .tgz must contain a single directory");
- if (chdir(dirname.c_str()) < 0)
- fatalerror("Chdir failed");
- executor = "./executor";
- } else {
- fatalerror("Failed to list work directory");
- }
}
}
}
@@ -265,8 +235,11 @@ void ExecutorLauncher::fetchExecutor()
void ExecutorLauncher::setupEnvironment()
{
// Set up the environment as specified in the ExecutorInfo.
- foreach (const Environment::Variable& variable, environment.variables()) {
- utils::os::setenv(variable.name(), variable.value());
+ if (commandInfo.has_environment()) {
+ foreach (const Environment::Variable& variable,
+ commandInfo.environment().variables()) {
+ utils::os::setenv(variable.name(), variable.value());
+ }
}
// Set Mesos environment variables for slave ID, framework ID, etc.
@@ -295,9 +268,21 @@ void ExecutorLauncher::setupEnvironmentF
// Set up Mesos environment variables that launcher/main.cpp will
// pass as arguments to an ExecutorLauncher there.
+ string uris = "";
+ foreach (const CommandInfo::URI& uri, commandInfo.uris()) {
+ uris += uri.value() + "+" +
+ (uri.has_executable() && uri.executable() ? "1" : "0");
+ uris += " ";
+ }
+
+ // Remove extra space at the end.
+ if (uris.size() > 0) {
+ uris = strings::trim(uris);
+ }
+
utils::os::setenv("MESOS_FRAMEWORK_ID", frameworkId.value());
- utils::os::setenv("MESOS_EXECUTOR_URI", executorUri);
- utils::os::setenv("MESOS_COMMAND", command);
+ utils::os::setenv("MESOS_COMMAND", commandInfo.value());
+ utils::os::setenv("MESOS_EXECUTOR_URIS", uris);
utils::os::setenv("MESOS_USER", user);
utils::os::setenv("MESOS_WORK_DIRECTORY", workDirectory);
utils::os::setenv("MESOS_SLAVE_PID", slavePid);
Modified: incubator/mesos/trunk/src/launcher/launcher.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/launcher/launcher.hpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/launcher/launcher.hpp (original)
+++ incubator/mesos/trunk/src/launcher/launcher.hpp Tue Mar 27 06:03:46 2012
@@ -44,8 +44,7 @@ public:
ExecutorLauncher(
const FrameworkID& frameworkId,
const ExecutorID& executorId,
- const std::string& executorUri,
- const std::string& command,
+ const CommandInfo& commandInfo,
const std::string& user,
const std::string& workDirectory,
const std::string& slavePid,
@@ -53,8 +52,7 @@ public:
const std::string& hadoopHome,
bool redirectIO,
bool shouldSwitchUser,
- const std::string& container,
- const Environment& environment);
+ const std::string& container);
virtual ~ExecutorLauncher();
@@ -73,10 +71,11 @@ protected:
// Initialize executor's working director.
virtual void initializeWorkingDirectory();
- // Download the executor's binary if required and return its path.
+ // Download the required files for the executor from the given set of URIs.
+ // Optionally, it will set the executable file permissions for the files.
// This method is expected to place files in the current directory
// (which will be the workDirectory).
- virtual void fetchExecutor();
+ virtual void fetchExecutors();
// Set up environment variables for launching a framework's executor.
virtual void setupEnvironment();
@@ -87,8 +86,7 @@ protected:
protected:
FrameworkID frameworkId;
ExecutorID executorId;
- std::string executorUri;
- std::string command;
+ CommandInfo commandInfo;
std::string user;
std::string workDirectory; // Directory in which the framework should run.
std::string slavePid;
@@ -97,7 +95,6 @@ protected:
bool redirectIO; // Whether to redirect stdout and stderr to files.
bool shouldSwitchUser; // Whether to setuid to framework's user.
std::string container;
- Environment environment;
};
} // namespace launcher {
Modified: incubator/mesos/trunk/src/launcher/main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/launcher/main.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/launcher/main.cpp (original)
+++ incubator/mesos/trunk/src/launcher/main.cpp Tue Mar 27 06:03:46 2012
@@ -18,6 +18,7 @@
#include <mesos/mesos.hpp>
+#include "common/strings.hpp"
#include "common/utils.hpp"
#include "launcher/launcher.hpp"
@@ -36,11 +37,27 @@ int main(int argc, char** argv)
ExecutorID executorId;
executorId.set_value(utils::os::getenv("MESOS_EXECUTOR_ID"));
+ CommandInfo commandInfo;
+ commandInfo.set_value(utils::os::getenv("MESOS_COMMAND"));
+
+ // Construct URIs from the encoded environment string.
+ const std::string& uris = utils::os::getenv("MESOS_EXECUTOR_URIS");
+ foreach (const std::string& token, strings::split(uris, " ")) {
+ size_t pos = token.rfind("+"); // Delim between uri and exec permission.
+ CHECK(pos != std::string::npos) << "Invalid executor uri token in env "
+ << token;
+
+ CommandInfo::URI uri;
+ uri.set_value(token.substr(0, pos));
+ uri.set_executable(token.substr(pos + 1) == "1");
+
+ commandInfo.add_uris()->MergeFrom(uri);
+ }
+
return mesos::internal::launcher::ExecutorLauncher(
frameworkId,
executorId,
- utils::os::getenv("MESOS_EXECUTOR_URI"),
- utils::os::getenv("MESOS_COMMAND"),
+ commandInfo,
utils::os::getenv("MESOS_USER"),
utils::os::getenv("MESOS_WORK_DIRECTORY"),
utils::os::getenv("MESOS_SLAVE_PID"),
@@ -48,6 +65,6 @@ int main(int argc, char** argv)
utils::os::getenv("MESOS_HADOOP_HOME"),
utils::os::getenv("MESOS_REDIRECT_IO") == "1",
utils::os::getenv("MESOS_SWITCH_USER") == "1",
- utils::os::getenv("MESOS_CONTAINER", false),
- Environment()).run();
+ utils::os::getenv("MESOS_CONTAINER", false))
+ .run();
}
Modified: incubator/mesos/trunk/src/slave/http.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/http.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/http.cpp (original)
+++ incubator/mesos/trunk/src/slave/http.cpp Tue Mar 27 06:03:46 2012
@@ -65,7 +65,6 @@ JSON::Object model(const Executor& execu
{
JSON::Object object;
object.values["id"] = executor.id.value();
- object.values["uri"] = executor.info.command().uri();
object.values["directory"] = executor.directory;
object.values["resources"] = model(executor.resources);
Modified: incubator/mesos/trunk/src/slave/lxc_isolation_module.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/lxc_isolation_module.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/lxc_isolation_module.cpp (original)
+++ incubator/mesos/trunk/src/slave/lxc_isolation_module.cpp Tue Mar 27 06:03:46 2012
@@ -174,17 +174,15 @@ void LxcIsolationModule::launchExecutor(
ExecutorLauncher* launcher =
new ExecutorLauncher(frameworkId,
executorId,
- executorInfo.command().uri(),
- executorInfo.command().value(),
+ executorInfo.command(),
frameworkInfo.user(),
- directory,
+ directory,
slave,
conf.get("frameworks_home", ""),
conf.get("hadoop_home", ""),
!local,
conf.get("switch_user", true),
- container,
- executorInfo.command().environment());
+ container);
launcher->setupEnvironmentForLauncherMain();
Modified: incubator/mesos/trunk/src/slave/process_based_isolation_module.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/process_based_isolation_module.cpp?rev=1305740&r1=1305739&r2=1305740&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/process_based_isolation_module.cpp (original)
+++ incubator/mesos/trunk/src/slave/process_based_isolation_module.cpp Tue Mar 27 06:03:46 2012
@@ -89,7 +89,7 @@ void ProcessBasedIsolationModule::launch
const ExecutorID& executorId = executorInfo.executor_id();
LOG(INFO) << "Launching " << executorId
- << " (" << executorInfo.command().uri() << ")"
+ << " (" << executorInfo.command().value() << ")"
<< " in " << directory
<< " with resources " << resources
<< "' for framework " << frameworkId;
@@ -186,8 +186,7 @@ ExecutorLauncher* ProcessBasedIsolationM
{
return new ExecutorLauncher(frameworkId,
executorInfo.executor_id(),
- executorInfo.command().uri(),
- executorInfo.command().value(),
+ executorInfo.command(),
frameworkInfo.user(),
directory,
slave,
@@ -195,8 +194,7 @@ ExecutorLauncher* ProcessBasedIsolationM
conf.get("hadoop_home", ""),
!local,
conf.get("switch_user", true),
- "",
- executorInfo.command().environment());
+ "");
}