int main(int argc, char** argv) { if (argc != 2) { cerr << "Usage: " << argv[0] << " <master>" << endl; return -1; } // Find this executable's directory to locate executor. char buf[4096]; realpath(dirname(argv[0]), buf); string uri = string(buf) + "/long-lived-executor"; if (getenv("MESOS_BUILD_DIR")) { uri = string(getenv("MESOS_BUILD_DIR")) + "/src/long-lived-executor"; } ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(uri); LongLivedScheduler scheduler(executor); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Long Lived Framework (C++)"); MesosSchedulerDriver driver(&scheduler, framework, argv[1]); return driver.run() == DRIVER_STOPPED ? 0 : 1; }
int main(int argc, char** argv) { // Find this executable's directory to locate executor. string path = os::realpath(dirname(argv[0])).get(); string uri = path + "/test-executor"; if (getenv("MESOS_BUILD_DIR")) { uri = string(getenv("MESOS_BUILD_DIR")) + "/src/test-executor"; } mesos::internal::logging::Flags flags; string role; flags.add(&role, "role", "Role to use when registering", "*"); Option<string> master; flags.add(&master, "master", "ip:port of master to connect"); Try<Nothing> load = flags.load(None(), argc, argv); if (load.isError()) { cerr << load.error() << endl; usage(argv[0], flags); exit(1); } else if (master.isNone()) { cerr << "Missing --master" << endl; usage(argv[0], flags); exit(1); } ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(uri); executor.set_name("Test Executor (C++)"); executor.set_source("cpp_test"); TestScheduler scheduler(executor, role); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Test Framework (C++)"); framework.set_role(role); MesosSchedulerDriver driver(&scheduler, framework, master.get()); return driver.run() == DRIVER_STOPPED ? 0 : 1; }
// For use with a MockScheduler, for example: // EXPECT_CALL(sched, resourceOffers(_, _)) // .WillOnce(LaunchTasks(TASKS, CPUS, MEM)); // Launches up to TASKS no-op tasks, if possible, // each with CPUS cpus and MEM memory. ACTION_P4(LaunchTasks, tasks, cpus, mem, role) { SchedulerDriver* driver = arg0; std::vector<Offer> offers = arg1; int numTasks = tasks; int launched = 0; for (size_t i = 0; i < offers.size(); i++) { const Offer& offer = offers[i]; const Resources TASK_RESOURCES = Resources::parse( "cpus:" + stringify(cpus) + ";mem:" + stringify(mem)).get(); int nextTaskId = 0; std::vector<TaskInfo> tasks; Resources remaining = offer.resources(); while (TASK_RESOURCES <= remaining.flatten() && launched < numTasks) { TaskInfo task; task.set_name("TestTask"); task.mutable_task_id()->set_value(stringify(nextTaskId++)); task.mutable_slave_id()->MergeFrom(offer.slave_id()); ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(":"); task.mutable_executor()->MergeFrom(executor); Option<Resources> resources = remaining.find(TASK_RESOURCES, role); CHECK_SOME(resources); task.mutable_resources()->MergeFrom(resources.get()); remaining -= resources.get(); tasks.push_back(task); launched++; } driver->launchTasks(offer.id(), tasks); } }
Environment HookManager::slaveExecutorEnvironmentDecorator( ExecutorInfo executorInfo) { Lock lock(&mutex); foreachpair (const string& name, Hook* hook, availableHooks) { const Result<Environment>& result = hook->slaveExecutorEnvironmentDecorator(executorInfo); if (result.isSome()) { // Update executorInfo to include newer environment variables // so that the next hook module can extend the environment // variables instead of simply overwriting them. executorInfo.mutable_command()->mutable_environment()->MergeFrom( result.get()); } else if (result.isError()) { LOG(WARNING) << "Slave environment decorator hook failed for module '" << name << "': " << result.error(); } } return executorInfo.command().environment(); }
inline TaskInfo createTask( const Offer& offer, const std::string& command, const Option<mesos::ExecutorID>& executorId = None(), const std::string& name = "test-task", const std::string& id = UUID::random().toString()) { TaskInfo task; task.set_name(name); task.mutable_task_id()->set_value(id); task.mutable_slave_id()->CopyFrom(offer.slave_id()); task.mutable_resources()->CopyFrom(offer.resources()); if (executorId.isSome()) { ExecutorInfo executor; executor.mutable_executor_id()->CopyFrom(executorId.get()); executor.mutable_command()->set_value(command); task.mutable_executor()->CopyFrom(executor); } else { task.mutable_command()->set_value(command); } return task; }
int main(int argc, char** argv) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " <master> <balloon limit in MB>" << std::endl; return -1; } // Verify the balloon limit. Try<size_t> limit = numify<size_t>(argv[2]); if (limit.isError()) { std::cerr << "Balloon limit is not a valid number" << std::endl; return -1; } if (limit.get() < EXECUTOR_MEMORY_MB) { std::cerr << "Please use a balloon limit bigger than " << EXECUTOR_MEMORY_MB << " MB" << std::endl; } // Find this executable's directory to locate executor. std::string path = os::realpath(::dirname(argv[0])).get(); std::string uri = path + "/balloon-executor"; if (getenv("MESOS_BUILD_DIR")) { uri = std::string(::getenv("MESOS_BUILD_DIR")) + "/src/balloon-executor"; } ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(uri); executor.set_name("Balloon Executor"); executor.set_source("balloon_test"); Resource* mem = executor.add_resources(); mem->set_name("mem"); mem->set_type(Value::SCALAR); mem->mutable_scalar()->set_value(EXECUTOR_MEMORY_MB); BalloonScheduler scheduler(executor, limit.get()); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Balloon Framework (C++)"); // TODO(vinod): Make checkpointing the default when it is default // on the slave. if (os::hasenv("MESOS_CHECKPOINT")) { cout << "Enabling checkpoint for the framework" << endl; framework.set_checkpoint(true); } MesosSchedulerDriver* driver; if (os::hasenv("MESOS_AUTHENTICATE")) { cout << "Enabling authentication for the framework" << endl; if (!os::hasenv("DEFAULT_PRINCIPAL")) { EXIT(1) << "Expecting authentication principal in the environment"; } if (!os::hasenv("DEFAULT_SECRET")) { EXIT(1) << "Expecting authentication secret in the environment"; } Credential credential; credential.set_principal(getenv("DEFAULT_PRINCIPAL")); credential.set_secret(getenv("DEFAULT_SECRET")); framework.set_principal(getenv("DEFAULT_PRINCIPAL")); driver = new MesosSchedulerDriver( &scheduler, framework, argv[1], credential); } else { framework.set_principal("balloon-framework-cpp"); driver = new MesosSchedulerDriver( &scheduler, framework, argv[1]); } int status = driver->run() == DRIVER_STOPPED ? 0 : 1; // Ensure that the driver process terminates. driver->stop(); delete driver; return status; }
// This test verifies that an authorized task launch is successful. TEST_F(MasterAuthorizationTest, AuthorizedTask) { // Setup ACLs so that the framework can launch tasks as "foo". ACLs acls; mesos::ACL::RunTasks* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values(DEFAULT_FRAMEWORK_INFO.principal()); acl->mutable_users()->add_values("foo"); master::Flags flags = CreateMasterFlags(); flags.acls = acls; Try<PID<Master> > master = StartMaster(flags); ASSERT_SOME(master); // Create an authorized executor. ExecutorInfo executor; // Bug in gcc 4.1.*, must assign on next line. executor = CREATE_EXECUTOR_INFO("test-executor", "exit 1"); executor.mutable_command()->set_user("foo"); MockExecutor exec(executor.executor_id()); Try<PID<Slave> > slave = StartSlave(&exec); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)) .Times(1); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); // Create an authorized task. TaskInfo task; task.set_name("test"); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(executor); vector<TaskInfo> tasks; tasks.push_back(task); EXPECT_CALL(exec, registered(_, _, _, _)) .Times(1); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); driver.launchTasks(offers.get()[0].id(), tasks); AWAIT_READY(status); EXPECT_EQ(TASK_RUNNING, status.get().state()); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.stop(); driver.join(); Shutdown(); // Must shutdown before 'containerizer' gets deallocated. }
int main(int argc, char** argv) { if (argc != 2) { cerr << "Usage: " << argv[0] << " <master>" << endl; return -1; } // Find this executable's directory to locate executor. string path = os::realpath(dirname(argv[0])).get(); string uri = path + "/long-lived-executor"; if (getenv("MESOS_BUILD_DIR")) { uri = string(getenv("MESOS_BUILD_DIR")) + "/src/long-lived-executor"; } ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(uri); executor.set_name("Long Lived Executor (C++)"); executor.set_source("cpp_long_lived_framework"); LongLivedScheduler scheduler(executor); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Long Lived Framework (C++)"); // TODO(vinod): Make checkpointing the default when it is default // on the slave. if (os::hasenv("MESOS_CHECKPOINT")) { cout << "Enabling checkpoint for the framework" << endl; framework.set_checkpoint(true); } MesosSchedulerDriver* driver; if (os::hasenv("MESOS_AUTHENTICATE")) { cout << "Enabling authentication for the framework" << endl; if (!os::hasenv("DEFAULT_PRINCIPAL")) { EXIT(1) << "Expecting authentication principal in the environment"; } if (!os::hasenv("DEFAULT_SECRET")) { EXIT(1) << "Expecting authentication secret in the environment"; } Credential credential; credential.set_principal(getenv("DEFAULT_PRINCIPAL")); credential.set_secret(getenv("DEFAULT_SECRET")); framework.set_principal(getenv("DEFAULT_PRINCIPAL")); driver = new MesosSchedulerDriver( &scheduler, framework, argv[1], credential); } else { framework.set_principal("long-lived-framework-cpp"); driver = new MesosSchedulerDriver( &scheduler, framework, argv[1]); } int status = driver->run() == DRIVER_STOPPED ? 0 : 1; // Ensure that the driver process terminates. driver->stop(); delete driver; return status; }
int main(int argc, char** argv) { if (argc != 2) { cerr << "Usage: " << argv[0] << " <master>" << endl; return -1; } // Find this executable's directory to locate executor. string uri; Option<string> value = os::getenv("MESOS_BUILD_DIR"); if (value.isSome()) { uri = path::join(value.get(), "src", "long-lived-executor"); } else { uri = path::join( os::realpath(Path(argv[0]).dirname()).get(), "long-lived-executor"); } ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(uri); executor.set_name("Long Lived Executor (C++)"); executor.set_source("cpp_long_lived_framework"); LongLivedScheduler scheduler(executor); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Long Lived Framework (C++)"); value = os::getenv("MESOS_CHECKPOINT"); if (value.isSome()) { framework.set_checkpoint( numify<bool>(value.get()).get()); } MesosSchedulerDriver* driver; if (os::getenv("MESOS_AUTHENTICATE").isSome()) { cout << "Enabling authentication for the framework" << endl; value = os::getenv("DEFAULT_PRINCIPAL"); if (value.isNone()) { EXIT(1) << "Expecting authentication principal in the environment"; } Credential credential; credential.set_principal(value.get()); framework.set_principal(value.get()); value = os::getenv("DEFAULT_SECRET"); if (value.isNone()) { EXIT(1) << "Expecting authentication secret in the environment"; } credential.set_secret(value.get()); driver = new MesosSchedulerDriver( &scheduler, framework, argv[1], credential); } else { framework.set_principal("long-lived-framework-cpp"); driver = new MesosSchedulerDriver( &scheduler, framework, argv[1]); } int status = driver->run() == DRIVER_STOPPED ? 0 : 1; // Ensure that the driver process terminates. driver->stop(); delete driver; return status; }
// This test verifies that authorization based endpoint filtering // works correctly on the /state endpoint. // Both default users are allowed to view high level frameworks, but only // one is allowed to view the tasks. // After launching a single task per each framework, one for role "superhero" // and the other for role "muggle", this test verifies that each of two // default users can view resource allocations and resource reservations for // corresponding allowed roles only. TYPED_TEST(SlaveAuthorizerTest, FilterStateEndpoint) { ACLs acls; const string roleSuperhero = "superhero"; const string roleMuggle = "muggle"; { // Default principal can see all frameworks. mesos::ACL::ViewFramework* acl = acls.add_view_frameworks(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_users()->set_type(ACL::Entity::ANY); } { // Second default principal can see all frameworks. mesos::ACL::ViewFramework* acl = acls.add_view_frameworks(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL_2.principal()); acl->mutable_users()->set_type(ACL::Entity::ANY); } { // No other principal can see frameworks running under any user. ACL::ViewFramework* acl = acls.add_view_frameworks(); acl->mutable_principals()->set_type(ACL::Entity::ANY); acl->mutable_users()->set_type(ACL::Entity::NONE); } { // Default principal can see all executors. mesos::ACL::ViewExecutor* acl = acls.add_view_executors(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_users()->set_type(ACL::Entity::ANY); } { // No other principal can see executors running under any user. ACL::ViewExecutor* acl = acls.add_view_executors(); acl->mutable_principals()->set_type(ACL::Entity::ANY); acl->mutable_users()->set_type(ACL::Entity::NONE); } { // Default principal can see all tasks. mesos::ACL::ViewTask* acl = acls.add_view_tasks(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_users()->set_type(ACL::Entity::ANY); } { // No other principal can see tasks running under any user. ACL::ViewTask* acl = acls.add_view_tasks(); acl->mutable_principals()->set_type(ACL::Entity::ANY); acl->mutable_users()->set_type(ACL::Entity::NONE); } { // Default principal can view "superhero" role only. ACL::ViewRole* acl = acls.add_view_roles(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_roles()->add_values(roleSuperhero); acl = acls.add_view_roles(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE); } { // Second default principal can view "muggle" role only. ACL::ViewRole* acl = acls.add_view_roles(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL_2.principal()); acl->mutable_roles()->add_values(roleMuggle); acl = acls.add_view_roles(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL_2.principal()); acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Owned<cluster::Master>> master = this->StartMaster(authorizer.get()); ASSERT_SOME(master); // Register framework with user "bar" and role "superhero". FrameworkInfo frameworkSuperhero = DEFAULT_FRAMEWORK_INFO; frameworkSuperhero.set_name("framework-" + roleSuperhero); frameworkSuperhero.set_roles(0, roleSuperhero); frameworkSuperhero.set_user("bar"); // Create an executor with user "bar". ExecutorInfo executorSuperhero = createExecutorInfo("test-executor-" + roleSuperhero, "sleep 2"); executorSuperhero.mutable_command()->set_user("bar"); MockExecutor execSuperhero(executorSuperhero.executor_id()); // Register framework with user "foo" and role "muggle". FrameworkInfo frameworkMuggle = DEFAULT_FRAMEWORK_INFO; frameworkMuggle.set_name("framework-" + roleMuggle); frameworkMuggle.set_principal(DEFAULT_CREDENTIAL_2.principal()); frameworkMuggle.set_roles(0, roleMuggle); frameworkMuggle.set_user("foo"); // Create an executor with user "foo". ExecutorInfo executorMuggle = createExecutorInfo("test-executor-" + roleMuggle, "sleep 2"); executorMuggle.mutable_command()->set_user("foo"); MockExecutor execMuggle(executorMuggle.executor_id()); TestContainerizer containerizer( {{executorSuperhero.executor_id(), &execSuperhero}, {executorMuggle.executor_id(), &execMuggle}}); slave::Flags flags = this->CreateSlaveFlags(); // Statically reserve resources for each role. flags.resources = "cpus(" + roleSuperhero + "):2;" + "cpus(" + roleMuggle + "):3;mem(" + roleSuperhero + "):512;" + "mem(" + roleMuggle + "):1024;"; Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = this->StartSlave( detector.get(), &containerizer, authorizer.get(), flags); ASSERT_SOME(slave); MockScheduler schedSuperhero; MesosSchedulerDriver driverSuperhero( &schedSuperhero, frameworkSuperhero, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(execSuperhero, registered(_, _, _, _)) .Times(AtMost(1)); Future<FrameworkID> frameworkIdSuperhero; EXPECT_CALL(schedSuperhero, registered(&driverSuperhero, _, _)) .WillOnce(FutureArg<1>(&frameworkIdSuperhero)); Future<vector<Offer>> offersSuperhero; EXPECT_CALL(schedSuperhero, resourceOffers(&driverSuperhero, _)) .WillOnce(FutureArg<1>(&offersSuperhero)) .WillRepeatedly(Return()); // Ignore subsequent offers. driverSuperhero.start(); AWAIT_READY(frameworkIdSuperhero); AWAIT_READY(offersSuperhero); ASSERT_FALSE(offersSuperhero->empty()); // Define a task which will run on executorSuperhero of frameworkSuperhero. TaskInfo taskSuperhero; taskSuperhero.set_name("test-" + roleSuperhero); taskSuperhero.mutable_task_id()->set_value("1"); taskSuperhero.mutable_slave_id()->MergeFrom( offersSuperhero.get()[0].slave_id()); taskSuperhero.mutable_resources()->MergeFrom( offersSuperhero.get()[0].resources()); taskSuperhero.mutable_executor()->MergeFrom(executorSuperhero); EXPECT_CALL(execSuperhero, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)) .WillRepeatedly(Return()); Future<TaskStatus> statusSuperhero; EXPECT_CALL(schedSuperhero, statusUpdate(&driverSuperhero, _)) .WillOnce(FutureArg<1>(&statusSuperhero)); driverSuperhero.launchTasks(offersSuperhero.get()[0].id(), {taskSuperhero}); AWAIT_READY(statusSuperhero); EXPECT_EQ(TASK_RUNNING, statusSuperhero->state()); MockScheduler schedMuggle; MesosSchedulerDriver driverMuggle( &schedMuggle, frameworkMuggle, master.get()->pid, DEFAULT_CREDENTIAL_2); EXPECT_CALL(execMuggle, registered(_, _, _, _)) .Times(AtMost(1)); Future<FrameworkID> frameworkIdMuggle; EXPECT_CALL(schedMuggle, registered(&driverMuggle, _, _)) .WillOnce(FutureArg<1>(&frameworkIdMuggle)); Future<vector<Offer>> offersMuggle; EXPECT_CALL(schedMuggle, resourceOffers(&driverMuggle, _)) .WillOnce(FutureArg<1>(&offersMuggle)) .WillRepeatedly(Return()); // Ignore subsequent offers. driverMuggle.start(); AWAIT_READY(frameworkIdMuggle); AWAIT_READY(offersMuggle); ASSERT_FALSE(offersMuggle->empty()); // Define a task which will run on executorMuggle of frameworkMuggle. TaskInfo taskMuggle; taskMuggle.set_name("test-" + roleMuggle); taskMuggle.mutable_task_id()->set_value("2"); taskMuggle.mutable_slave_id()->MergeFrom( offersMuggle.get()[0].slave_id()); taskMuggle.mutable_resources()->MergeFrom( offersMuggle.get()[0].resources()); taskMuggle.mutable_executor()->MergeFrom(executorMuggle); EXPECT_CALL(execMuggle, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)) .WillRepeatedly(Return()); Future<TaskStatus> statusMuggle; EXPECT_CALL(schedMuggle, statusUpdate(&driverMuggle, _)) .WillOnce(FutureArg<1>(&statusMuggle)); driverMuggle.launchTasks(offersMuggle.get()[0].id(), {taskMuggle}); AWAIT_READY(statusMuggle); ASSERT_EQ(TASK_RUNNING, statusMuggle->state()); // Retrieve endpoint with the user allowed to view the frameworks. // The default user allowed to view role "superhero" only. { Future<Response> response = http::get( slave.get()->pid, "state", None(), createBasicAuthHeaders(DEFAULT_CREDENTIAL)); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); Try<JSON::Object> parse = JSON::parse<JSON::Object>(response->body); ASSERT_SOME(parse); JSON::Object state = parse.get(); ASSERT_TRUE(state.values["frameworks"].is<JSON::Array>()); JSON::Array frameworks = state.values["frameworks"].as<JSON::Array>(); EXPECT_EQ(2u, frameworks.values.size()); foreach (const JSON::Value& value, frameworks.values) { JSON::Object framework = value.as<JSON::Object>(); EXPECT_FALSE(framework.values.empty()); ASSERT_TRUE(framework.values["executors"].is<JSON::Array>()); JSON::Array executors = framework.values["executors"].as<JSON::Array>(); EXPECT_EQ(1u, executors.values.size()); JSON::Object executor = executors.values.front().as<JSON::Object>(); EXPECT_EQ(1u, executor.values["tasks"].as<JSON::Array>().values.size()); } ASSERT_TRUE(state.values["reserved_resources"].is<JSON::Object>()); JSON::Object reserved_resources = state.values["reserved_resources"].as<JSON::Object>(); EXPECT_TRUE(reserved_resources.values[roleSuperhero].is<JSON::Object>()); EXPECT_FALSE(reserved_resources.values[roleMuggle].is<JSON::Object>()); ASSERT_TRUE( state.values["reserved_resources_allocated"].is<JSON::Object>()); JSON::Object reserved_resources_allocated = state.values["reserved_resources_allocated"].as<JSON::Object>(); EXPECT_TRUE( reserved_resources_allocated.values[roleSuperhero].is<JSON::Object>()); EXPECT_FALSE( reserved_resources_allocated.values[roleMuggle].is<JSON::Object>()); ASSERT_TRUE(state.values["reserved_resources_full"].is<JSON::Object>()); JSON::Object reserved_resources_full = state.values["reserved_resources_full"].as<JSON::Object>(); EXPECT_TRUE( reserved_resources_full.values[roleSuperhero].is<JSON::Array>()); EXPECT_FALSE( reserved_resources_full.values[roleMuggle].is<JSON::Array>()); } // Retrieve endpoint with the user allowed to view the frameworks, // but not the executors. // The second default user allowed to view role "muggle" only. { Future<Response> response = http::get( slave.get()->pid, "state", None(), createBasicAuthHeaders(DEFAULT_CREDENTIAL_2)); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); Try<JSON::Object> parse = JSON::parse<JSON::Object>(response->body); ASSERT_SOME(parse); JSON::Object state = parse.get(); ASSERT_TRUE(state.values["frameworks"].is<JSON::Array>()); JSON::Array frameworks = state.values["frameworks"].as<JSON::Array>(); EXPECT_EQ(2u, frameworks.values.size()); foreach (const JSON::Value& value, frameworks.values) { JSON::Object framework = value.as<JSON::Object>(); EXPECT_FALSE(framework.values.empty()); EXPECT_TRUE( framework.values["executors"].as<JSON::Array>().values.empty()); } ASSERT_TRUE(state.values["reserved_resources"].is<JSON::Object>()); JSON::Object reserved_resources = state.values["reserved_resources"].as<JSON::Object>(); EXPECT_TRUE(reserved_resources.values[roleMuggle].is<JSON::Object>()); EXPECT_FALSE(reserved_resources.values[roleSuperhero].is<JSON::Object>()); ASSERT_TRUE( state.values["reserved_resources_allocated"].is<JSON::Object>()); JSON::Object reserved_resources_allocated = state.values["reserved_resources_allocated"].as<JSON::Object>(); EXPECT_TRUE( reserved_resources_allocated.values[roleMuggle].is<JSON::Object>()); EXPECT_FALSE( reserved_resources_allocated.values[roleSuperhero].is<JSON::Object>()); ASSERT_TRUE(state.values["reserved_resources_full"].is<JSON::Object>()); JSON::Object reserved_resources_full = state.values["reserved_resources_full"].as<JSON::Object>(); EXPECT_TRUE( reserved_resources_full.values[roleMuggle].is<JSON::Array>()); EXPECT_FALSE( reserved_resources_full.values[roleSuperhero].is<JSON::Array>()); } EXPECT_CALL(execSuperhero, shutdown(_)) .Times(AtMost(1)); EXPECT_CALL(execMuggle, shutdown(_)) .Times(AtMost(1)); driverSuperhero.stop(); driverSuperhero.join(); driverMuggle.stop(); driverMuggle.join(); }
TEST_F(MultipleExecutorsTest, TasksExecutorInfoDiffers) { Try<PID<Master> > master = StartMaster(); ASSERT_SOME(master); MockExecutor exec(DEFAULT_EXECUTOR_ID); Try<PID<Slave> > slave = StartSlave(&exec); ASSERT_SOME(master); MockScheduler sched; MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get()); EXPECT_CALL(sched, registered(&driver, _, _)) .Times(1); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value("exit 1"); TaskInfo task1; task1.set_name(""); task1.mutable_task_id()->set_value("1"); task1.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task1.mutable_resources()->MergeFrom(Resources::parse("cpus:1;mem:512").get()); task1.mutable_executor()->MergeFrom(executor); executor.mutable_command()->set_value("exit 2"); TaskInfo task2; task2.set_name(""); task2.mutable_task_id()->set_value("2"); task2.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task2.mutable_resources()->MergeFrom(Resources::parse("cpus:1;mem:512").get()); task2.mutable_executor()->MergeFrom(executor); vector<TaskInfo> tasks; tasks.push_back(task1); tasks.push_back(task2); EXPECT_CALL(exec, registered(_, _, _, _)) .Times(1); // Grab the "good" task but don't send a status update. Future<TaskInfo> task; EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(FutureArg<1>(&task)); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); driver.launchTasks(offers.get()[0].id(), tasks); AWAIT_READY(task); EXPECT_EQ(task1.task_id(), task.get().task_id()); AWAIT_READY(status); EXPECT_EQ(task2.task_id(), status.get().task_id()); EXPECT_EQ(TASK_LOST, status.get().state()); EXPECT_TRUE(status.get().has_message()); EXPECT_EQ("Task has invalid ExecutorInfo (existing ExecutorInfo" " with same ExecutorID is not compatible)", status.get().message()); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.stop(); driver.join(); Shutdown(); }
int main(int argc, char** argv) { // Find this executable's directory to locate executor. string path = os::realpath(dirname(argv[0])).get(); string uri = path + "/test-executor"; if (getenv("MESOS_BUILD_DIR")) { uri = string(getenv("MESOS_BUILD_DIR")) + "/src/test-executor"; } mesos::internal::logging::Flags flags; string role; flags.add(&role, "role", "Role to use when registering", "*"); Option<string> master; flags.add(&master, "master", "ip:port of master to connect"); Try<Nothing> load = flags.load(None(), argc, argv); if (load.isError()) { cerr << load.error() << endl; usage(argv[0], flags); exit(1); } else if (master.isNone()) { cerr << "Missing --master" << endl; usage(argv[0], flags); exit(1); } ExecutorInfo executor; executor.mutable_executor_id()->set_value("default"); executor.mutable_command()->set_value(uri); executor.set_name("Test Executor (C++)"); executor.set_source("cpp_test"); TestScheduler scheduler(executor, role); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Test Framework (C++)"); framework.set_role(role); // TODO(vinod): Make checkpointing the default when it is default // on the slave. if (os::hasenv("MESOS_CHECKPOINT")) { cout << "Enabling checkpoint for the framework" << endl; framework.set_checkpoint(true); } MesosSchedulerDriver* driver; if (os::hasenv("MESOS_AUTHENTICATE")) { cout << "Enabling authentication for the framework" << endl; if (!os::hasenv("DEFAULT_PRINCIPAL")) { EXIT(1) << "Expecting authentication principal in the environment"; } if (!os::hasenv("DEFAULT_SECRET")) { EXIT(1) << "Expecting authentication secret in the environment"; } Credential credential; credential.set_principal(getenv("DEFAULT_PRINCIPAL")); credential.set_secret(getenv("DEFAULT_SECRET")); driver = new MesosSchedulerDriver( &scheduler, framework, master.get(), credential); } else { driver = new MesosSchedulerDriver( &scheduler, framework, master.get()); } int status = driver->run() == DRIVER_STOPPED ? 0 : 1; delete driver; return status; }
int main(int argc, char** argv) { string seedUrl, master; shift; while (true) { string s = argc>0 ? argv[0] : "--help"; if (argc > 1 && s == "--seedUrl") { seedUrl = argv[1]; shift; shift; } else if (argc > 1 && s == "--master") { master = argv[1]; shift; shift; } else { break; } } if (master.length() == 0 || seedUrl.length() == 0) { printf("Usage: rendler --seedUrl <URL> --master <ip>:<port>\n"); exit(1); } // Find this executable's directory to locate executor. string path = realpath(dirname(argv[0]), NULL); string crawlerURI = path + "/crawl_executor"; string rendererURI = path + "/render_executor"; cout << crawlerURI << endl; cout << rendererURI << endl; ExecutorInfo crawler; crawler.mutable_executor_id()->set_value("Crawler"); crawler.mutable_command()->set_value(crawlerURI); crawler.set_name("Crawl Executor (C++)"); crawler.set_source("cpp"); ExecutorInfo renderer; renderer.mutable_executor_id()->set_value("Renderer"); renderer.mutable_command()->set_value(rendererURI); renderer.set_name("Render Executor (C++)"); renderer.set_source("cpp"); Rendler scheduler(crawler, renderer, seedUrl); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_name("Rendler Framework (C++)"); //framework.set_role(role); framework.set_principal("rendler-cpp"); // Set up the signal handler for SIGINT for clean shutdown. struct sigaction action; action.sa_handler = SIGINTHandler; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGINT, &action, NULL); schedulerDriver = new MesosSchedulerDriver(&scheduler, framework, master); int status = schedulerDriver->run() == DRIVER_STOPPED ? 0 : 1; // Ensure that the driver process terminates. schedulerDriver->stop(); shutdown(); delete schedulerDriver; return status; }