Try<Subprocess> run( const string& _command, const Option<string>& rootfs = None()) { slave::MesosContainerizerLaunch::Flags launchFlags; CommandInfo command; command.set_value(_command); launchFlags.command = JSON::protobuf(command); launchFlags.sandbox = "/tmp"; launchFlags.pipe_read = open("/dev/zero", O_RDONLY); launchFlags.pipe_write = open("/dev/null", O_WRONLY); launchFlags.rootfs = rootfs; vector<string> argv(2); argv[0] = "mesos-containerizer"; argv[1] = slave::MesosContainerizerLaunch::NAME; Try<Subprocess> s = subprocess( path::join(getLauncherDir(), "mesos-containerizer"), argv, Subprocess::PATH("/dev/null"), Subprocess::FD(STDOUT_FILENO), Subprocess::FD(STDERR_FILENO), launchFlags, None(), None(), lambda::bind(&os::clone, lambda::_1, CLONE_NEWNS | SIGCHLD)); close(launchFlags.pipe_read.get()); close(launchFlags.pipe_write.get()); return s; }
// Add available ContainerLogger modules. static void addContainerLoggerModules(Modules* modules) { CHECK_NOTNULL(modules); // Add our test container logger module. Modules::Library* library = modules->add_libraries(); library->set_file(getModulePath("testcontainer_logger")); // To add a new module from this library, create a new ModuleID enum // and tie it with a module name. addModule(library, TestSandboxContainerLogger, "org_apache_mesos_TestSandboxContainerLogger"); // Add the second container logger module. library = modules->add_libraries(); library->set_file(getModulePath("logrotate_container_logger")); addModule(library, LogrotateContainerLogger, "org_apache_mesos_LogrotateContainerLogger"); // Pass in the directory for the binary test sources. Modules::Library::Module* module = library->mutable_modules(0); mesos::Parameter* moduleParameter = module->add_parameters(); moduleParameter->set_key("launcher_dir"); moduleParameter->set_value(getLauncherDir()); // Set the size and number of log files to keep. moduleParameter = module->add_parameters(); moduleParameter->set_key("max_stdout_size"); moduleParameter->set_value(stringify(Megabytes(2))); // NOTE: This is a 'logrotate' configuration option. // It means to "rotate" a file 4 times before removal. moduleParameter = module->add_parameters(); moduleParameter->set_key("logrotate_stdout_options"); moduleParameter->set_value("rotate 4"); }
void execute(const string& script) { // Create a temporary directory for the test. Try<string> directory = environment->mkdtemp(); CHECK_SOME(directory) << "Failed to create temporary directory"; if (flags.verbose) { std::cerr << "Using temporary directory '" << directory.get() << "'" << std::endl; } // Determine the path for the script. Result<string> path = os::realpath(getTestScriptPath(script)); if (!path.isSome()) { FAIL() << "Failed to locate script " << script << ": " << (path.isError() ? path.error() : "No such file or directory"); } // Fork a process to change directory and run the test. pid_t pid; if ((pid = fork()) == -1) { FAIL() << "Failed to fork to launch script"; } if (pid > 0) { // In parent process. int status; while (wait(&status) != pid || WIFSTOPPED(status)); CHECK(WIFEXITED(status) || WIFSIGNALED(status)); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { FAIL() << script << " " << WSTRINGIFY(status); } } else { // In child process. DO NOT USE GLOG! // Start by cd'ing into the temporary directory. Try<Nothing> chdir = os::chdir(directory.get()); if (chdir.isError()) { std::cerr << "Failed to chdir to '" << directory.get() << "': " << chdir.error() << std::endl; abort(); } // Redirect output to /dev/null unless the test is verbose. if (!flags.verbose) { if (freopen("/dev/null", "w", stdout) == NULL || freopen("/dev/null", "w", stderr) == NULL) { std::cerr << "Failed to redirect stdout/stderr to /dev/null:" << os::strerror(errno) << std::endl; abort(); } } // Set up the environment for executing the script. We might be running from // the Mesos source tree or from an installed version of the tests. In the // latter case, all of the variables below are swizzled to point to the // installed locations, except MESOS_SOURCE_DIR. Scripts that make use of // MESOS_SOURCE_DIR are expected to gracefully degrade if the Mesos source // is no longer present. os::setenv("MESOS_BUILD_DIR", flags.build_dir); os::setenv("MESOS_HELPER_DIR", getTestHelperDir()); os::setenv("MESOS_LAUNCHER_DIR", getLauncherDir()); os::setenv("MESOS_SBIN_DIR", getSbinDir()); os::setenv("MESOS_SOURCE_DIR", flags.source_dir); os::setenv("MESOS_WEBUI_DIR", getWebUIDir()); // Enable replicated log based registry. os::setenv("MESOS_REGISTRY", "replicated_log"); // Enable authentication. os::setenv("MESOS_AUTHENTICATE", "true"); // Create test credentials. const string& credentials = DEFAULT_CREDENTIAL.principal() + " " + DEFAULT_CREDENTIAL.secret(); const string& credentialsPath = path::join(directory.get(), "credentials"); CHECK_SOME(os::write(credentialsPath, credentials)) << "Failed to write credentials to '" << credentialsPath << "'"; os::setenv("MESOS_CREDENTIALS", "file://" + credentialsPath); // We set test credentials here for example frameworks to use. os::setenv("DEFAULT_PRINCIPAL", DEFAULT_CREDENTIAL.principal()); os::setenv("DEFAULT_SECRET", DEFAULT_CREDENTIAL.secret()); // TODO(bmahler): Update the example frameworks to use flags and // remove the special DEFAULT_* environment variables above. os::setenv("MESOS_PRINCIPAL", DEFAULT_CREDENTIAL.principal()); os::setenv("MESOS_SECRET", DEFAULT_CREDENTIAL.secret()); // Create test ACLs. ACLs acls; acls.set_permissive(false); mesos::ACL::RunTask* run = acls.add_run_tasks(); run->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); Result<string> user = os::user(); CHECK_SOME(user) << "Failed to get current user name"; run->mutable_users()->add_values(user.get()); mesos::ACL::RegisterFramework* register_ = acls.add_register_frameworks(); register_->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); register_->mutable_roles()->add_values("*"); const string& aclsPath = path::join(directory.get(), "acls"); CHECK_SOME(os::write(aclsPath, stringify(JSON::protobuf(acls)))) << "Failed to write ACLs to '" << aclsPath << "'"; os::setenv("MESOS_ACLS", "file://" + aclsPath); // Now execute the script. execl(path.get().c_str(), path.get().c_str(), (char*) NULL); std::cerr << "Failed to execute '" << script << "': " << os::strerror(errno) << std::endl; abort(); } }