TEST(DurationTest, Comparison) { EXPECT_EQ(Duration::zero(), Seconds(0)); EXPECT_EQ(Minutes(180), Hours(3)); EXPECT_EQ(Seconds(10800), Hours(3)); EXPECT_EQ(Milliseconds(10800000), Hours(3)); EXPECT_EQ(Milliseconds(1), Microseconds(1000)); EXPECT_EQ(Milliseconds(1000), Seconds(1)); EXPECT_GT(Weeks(1), Days(6)); EXPECT_LT(Hours(23), Days(1)); EXPECT_LE(Hours(24), Days(1)); EXPECT_GE(Hours(24), Days(1)); EXPECT_NE(Minutes(59), Hours(1)); // Maintains precision for a 100 year duration. EXPECT_GT(Weeks(5217) + Nanoseconds(1), Weeks(5217)); EXPECT_LT(Weeks(5217) - Nanoseconds(1), Weeks(5217)); }
// Ensures that the driver can handle the SUBSCRIBED event. TEST_F(SchedulerDriverEventTest, Subscribed) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); // Make sure the initial registration calls 'registered'. MockScheduler sched; MesosSchedulerDriver driver( &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL); // Intercept the registration message, send a SUBSCRIBED instead. Future<Message> frameworkRegisteredMessage = DROP_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); // Ensure that there will be no (re-)registration retries // from the scheduler driver. Clock::pause(); driver.start(); AWAIT_READY(frameworkRegisteredMessage); UPID frameworkPid = frameworkRegisteredMessage.get().to; FrameworkRegisteredMessage message; ASSERT_TRUE(message.ParseFromString(frameworkRegisteredMessage.get().body)); FrameworkID frameworkId = message.framework_id(); frameworkInfo.mutable_id()->CopyFrom(frameworkId); Event event; event.set_type(Event::SUBSCRIBED); event.mutable_subscribed()->mutable_framework_id()->CopyFrom(frameworkId); Future<Nothing> registered; EXPECT_CALL(sched, registered(&driver, frameworkId, _)) .WillOnce(FutureSatisfy(®istered)); process::post(master.get()->pid, frameworkPid, event); AWAIT_READY(registered); driver.stop(); driver.join(); }
namespace slave { const Duration EXECUTOR_REGISTRATION_TIMEOUT = Minutes(1); const Duration EXECUTOR_SHUTDOWN_GRACE_PERIOD = Seconds(5); const Duration EXECUTOR_REREGISTER_TIMEOUT = Seconds(2); const Duration EXECUTOR_SIGNAL_ESCALATION_TIMEOUT = Seconds(3); const Duration STATUS_UPDATE_RETRY_INTERVAL_MIN = Seconds(10); const Duration STATUS_UPDATE_RETRY_INTERVAL_MAX = Minutes(10); const Duration REGISTRATION_BACKOFF_FACTOR = Seconds(1); const Duration REGISTER_RETRY_INTERVAL_MAX = Minutes(1); const Duration GC_DELAY = Weeks(1); const double GC_DISK_HEADROOM = 0.1; const Duration DISK_WATCH_INTERVAL = Minutes(1); const Duration RECOVERY_TIMEOUT = Minutes(15); const Duration RESOURCE_MONITORING_INTERVAL = Seconds(1); const uint32_t MAX_COMPLETED_FRAMEWORKS = 50; const uint32_t MAX_COMPLETED_EXECUTORS_PER_FRAMEWORK = 150; const uint32_t MAX_COMPLETED_TASKS_PER_EXECUTOR = 200; const double DEFAULT_CPUS = 1; const Bytes DEFAULT_MEM = Gigabytes(1); const Bytes DEFAULT_DISK = Gigabytes(10); const std::string DEFAULT_PORTS = "[31000-32000]"; #ifdef WITH_NETWORK_ISOLATOR const uint16_t DEFAULT_EPHEMERAL_PORTS_PER_CONTAINER = 1024; #endif const Duration DOCKER_REMOVE_DELAY = Hours(6); const Duration DOCKER_INSPECT_DELAY = Seconds(1); // TODO(tnachen): Make this a flag. const Duration DOCKER_VERSION_WAIT_TIMEOUT = Seconds(5); const std::string DEFAULT_AUTHENTICATEE = "crammd5"; Duration DEFAULT_MASTER_PING_TIMEOUT() { return master::DEFAULT_SLAVE_PING_TIMEOUT * master::DEFAULT_MAX_SLAVE_PING_TIMEOUTS; } } // namespace slave {
// This test verifies that if master --> framework socket closes and the // framework is not aware of it (i.e., one way network partition), all // subsequent calls from the framework after the master has marked it as // disconnected would result in an error message causing the framework to abort. TEST_F(PartitionTest, OneWayPartitionMasterToScheduler) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); MockScheduler sched; StandaloneMasterDetector detector(master.get()->pid); TestingMesosSchedulerDriver driver(&sched, &detector, frameworkInfo); Future<process::Message> frameworkRegisteredMessage = FUTURE_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); Future<Nothing> registered; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureSatisfy(®istered)); driver.start(); AWAIT_READY(frameworkRegisteredMessage); AWAIT_READY(registered); Future<Nothing> error; EXPECT_CALL(sched, error(&driver, _)) .WillOnce(FutureSatisfy(&error)); // Simulate framework disconnection. This should result in an error message. ASSERT_TRUE(process::inject::exited( frameworkRegisteredMessage.get().to, master.get()->pid)); AWAIT_READY(error); driver.stop(); driver.join(); }
inline std::ostream& operator<<(std::ostream& stream, const Duration& duration_) { // Output the duration in full double precision and save the old precision. std::streamsize precision = stream.precision(std::numeric_limits<double>::digits10); // Parse the duration as the sign and the absolute value. Duration duration = duration_; if (duration_ < Duration::zero()) { stream << "-"; // Duration::min() may not be representable as a positive Duration. if (duration_ == Duration::min()) { duration = Duration::max(); } else { duration = duration_ * -1; } } // First determine which bucket of time unit the duration falls into // then check whether the duration can be represented as a whole // number with this time unit or a smaller one. // e.g. 1.42857142857143weeks falls into the 'Weeks' bucket but // reads better with a smaller unit: '10days'. So we use 'days' // instead of 'weeks' to output the duration. int64_t nanoseconds = duration.ns(); if (duration < Microseconds(1)) { stream << duration.ns() << Nanoseconds::units(); } else if (duration < Milliseconds(1)) { if (nanoseconds % Duration::MICROSECONDS != 0) { // We can't get a whole number using this unit but we can at // one level down. stream << duration.ns() << Nanoseconds::units(); } else { stream << duration.us() << Microseconds::units(); } } else if (duration < Seconds(1)) { if (nanoseconds % Duration::MILLISECONDS != 0 && nanoseconds % Duration::MICROSECONDS == 0) { stream << duration.us() << Microseconds::units(); } else { stream << duration.ms() << Milliseconds::units(); } } else if (duration < Minutes(1)) { if (nanoseconds % Duration::SECONDS != 0 && nanoseconds % Duration::MILLISECONDS == 0) { stream << duration.ms() << Milliseconds::units(); } else { stream << duration.secs() << Seconds::units(); } } else if (duration < Hours(1)) { if (nanoseconds % Duration::MINUTES != 0 && nanoseconds % Duration::SECONDS == 0) { stream << duration.secs() << Seconds::units(); } else { stream << duration.mins() << Minutes::units(); } } else if (duration < Days(1)) { if (nanoseconds % Duration::HOURS != 0 && nanoseconds % Duration::MINUTES == 0) { stream << duration.mins() << Minutes::units(); } else { stream << duration.hrs() << Hours::units(); } } else if (duration < Weeks(1)) { if (nanoseconds % Duration::DAYS != 0 && nanoseconds % Duration::HOURS == 0) { stream << duration.hrs() << Hours::units(); } else { stream << duration.days() << Days::units(); } } else { if (nanoseconds % Duration::WEEKS != 0 && nanoseconds % Duration::DAYS == 0) { stream << duration.days() << Days::units(); } else { stream << duration.weeks() << Weeks::units(); } } // Return the stream to original formatting state. stream.precision(precision); return stream; }
// Ensures that the driver can handle the SUBSCRIBED event // after a master failover. TEST_F(SchedulerDriverEventTest, SubscribedMasterFailover) { Try<PID<Master>> master = StartMaster(); ASSERT_SOME(master); FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); // Make sure the initial registration calls 'registered'. MockScheduler sched; StandaloneMasterDetector detector(master.get()); TestingMesosSchedulerDriver driver(&sched, &detector, frameworkInfo); // Intercept the registration message, send a SUBSCRIBED instead. Future<Message> frameworkRegisteredMessage = DROP_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); // Ensure that there will be no (re-)registration retries // from the scheduler driver. Clock::pause(); driver.start(); AWAIT_READY(frameworkRegisteredMessage); UPID frameworkPid = frameworkRegisteredMessage.get().to; FrameworkRegisteredMessage message; ASSERT_TRUE(message.ParseFromString(frameworkRegisteredMessage.get().body)); FrameworkID frameworkId = message.framework_id(); frameworkInfo.mutable_id()->CopyFrom(frameworkId); Event event; event.set_type(Event::SUBSCRIBED); event.mutable_subscribed()->mutable_framework_id()->CopyFrom(frameworkId); Future<Nothing> registered; EXPECT_CALL(sched, registered(&driver, frameworkId, _)) .WillOnce(FutureSatisfy(®istered)); process::post(master.get(), frameworkPid, event); AWAIT_READY(registered); // Fail over the master and expect a 'reregistered' call. // Note that the master sends a registered message for // this case (see MESOS-786). Stop(master.get()); master = StartMaster(); ASSERT_SOME(master); EXPECT_CALL(sched, disconnected(&driver)); frameworkRegisteredMessage = DROP_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); detector.appoint(master.get()); AWAIT_READY(frameworkRegisteredMessage); Future<Nothing> reregistered; EXPECT_CALL(sched, reregistered(&driver, _)) .WillOnce(FutureSatisfy(&reregistered)); process::post(master.get(), frameworkPid, event); AWAIT_READY(reregistered); }
// This test verifies that a framework attempting to subscribe // after its failover timeout has elapsed is disallowed. TEST_F(HttpFaultToleranceTest, SchedulerSubscribeAfterFailoverTimeout) { master::Flags flags = CreateMasterFlags(); flags.authenticate_frameworks = false; v1::FrameworkInfo frameworkInfo = v1::DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); Try<Owned<cluster::Master>> master = StartMaster(flags); ASSERT_SOME(master); Future<Nothing> deactivateFramework = FUTURE_DISPATCH( _, &master::allocator::MesosAllocatorProcess::deactivateFramework); v1::FrameworkID frameworkId; ContentType contentType = ContentType::PROTOBUF; // Launch the first (i.e., failing) scheduler and wait until it receives // a `SUBSCRIBED` event to launch the second (i.e., failover) scheduler. { auto scheduler = std::make_shared<v1::MockHTTPScheduler>(); Future<Nothing> connected; EXPECT_CALL(*scheduler, connected(_)) .WillOnce(FutureSatisfy(&connected)); v1::scheduler::TestMesos schedulerLibrary( master.get()->pid, contentType, scheduler); AWAIT_READY(connected); Future<Event::Subscribed> subscribed; EXPECT_CALL(*scheduler, subscribed(_, _)) .WillOnce(FutureArg<1>(&subscribed)); EXPECT_CALL(*scheduler, heartbeat(_)) .WillRepeatedly(Return()); // Ignore heartbeats. { Call call; call.set_type(Call::SUBSCRIBE); Call::Subscribe* subscribe = call.mutable_subscribe(); subscribe->mutable_framework_info()->CopyFrom(frameworkInfo); schedulerLibrary.send(call); } AWAIT_READY(subscribed); frameworkId = subscribed->framework_id(); } // Wait until master schedules the framework for removal. AWAIT_READY(deactivateFramework); // Simulate framework failover timeout. Clock::pause(); Clock::settle(); Try<Duration> failoverTimeout = Duration::create(frameworkInfo.failover_timeout()); ASSERT_SOME(failoverTimeout); Future<Nothing> frameworkFailoverTimeout = FUTURE_DISPATCH(_, &Master::frameworkFailoverTimeout); Clock::advance(failoverTimeout.get()); Clock::resume(); // Wait until master actually marks the framework as completed. AWAIT_READY(frameworkFailoverTimeout); // Now launch the second (i.e., failover) scheduler using the // framework id recorded from the first scheduler. { auto scheduler = std::make_shared<v1::MockHTTPScheduler>(); Future<Nothing> connected; EXPECT_CALL(*scheduler, connected(_)) .WillOnce(FutureSatisfy(&connected)) .WillRepeatedly(Return()); // Ignore future invocations. v1::scheduler::TestMesos schedulerLibrary( master.get()->pid, contentType, scheduler); AWAIT_READY(connected); // Framework should get `Error` event because the framework with this id // is marked as completed. Future<Nothing> error; EXPECT_CALL(*scheduler, error(_, _)) .WillOnce(FutureSatisfy(&error)); EXPECT_CALL(*scheduler, disconnected(_)) .Times(AtMost(1)); { Call call; call.mutable_framework_id()->CopyFrom(frameworkId); call.set_type(Call::SUBSCRIBE); Call::Subscribe* subscribe = call.mutable_subscribe(); subscribe->mutable_framework_info()->CopyFrom(v1::DEFAULT_FRAMEWORK_INFO); subscribe->mutable_framework_info()->mutable_id()->CopyFrom(frameworkId); schedulerLibrary.send(call); } AWAIT_READY(error); } }
// This test verifies if we are able to upgrade from a PID based // scheduler to HTTP scheduler. TEST_P(SchedulerHttpApiTest, UpdatePidToHttpScheduler) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); v1::FrameworkInfo frameworkInfo = v1::DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); MockScheduler sched; StandaloneMasterDetector detector(master.get()->pid); TestingMesosSchedulerDriver driver(&sched, &detector, devolve(frameworkInfo)); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId)); // Check that driver is notified with an error when the http // framework is connected. Future<FrameworkErrorMessage> errorMessage = FUTURE_PROTOBUF(FrameworkErrorMessage(), _, _); EXPECT_CALL(sched, error(_, _)); driver.start(); AWAIT_READY(frameworkId); EXPECT_NE("", frameworkId.get().value()); // Now try to subscribe as an HTTP framework. Call call; call.set_type(Call::SUBSCRIBE); call.mutable_framework_id()->CopyFrom(evolve(frameworkId.get())); Call::Subscribe* subscribe = call.mutable_subscribe(); subscribe->mutable_framework_info()->CopyFrom(frameworkInfo); subscribe->mutable_framework_info()->mutable_id()-> CopyFrom(evolve(frameworkId.get())); // Retrieve the parameter passed as content type to this test. const string contentType = GetParam(); process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL); headers["Accept"] = contentType; Future<Response> response = process::http::streaming::post( master.get()->pid, "api/v1/scheduler", headers, serialize(call, contentType), contentType); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_HEADER_EQ("chunked", "Transfer-Encoding", response); ASSERT_EQ(Response::PIPE, response.get().type); Option<Pipe::Reader> reader = response.get().reader; ASSERT_SOME(reader); auto deserializer = lambda::bind( &SchedulerHttpApiTest::deserialize, this, contentType, lambda::_1); Reader<Event> responseDecoder(Decoder<Event>(deserializer), reader.get()); Future<Result<Event>> event = responseDecoder.read(); AWAIT_READY(event); ASSERT_SOME(event.get()); // Check event type is subscribed and the framework id is set. ASSERT_EQ(Event::SUBSCRIBED, event.get().get().type()); EXPECT_EQ(evolve(frameworkId.get()), event.get().get().subscribed().framework_id()); // Make sure it receives a heartbeat. event = responseDecoder.read(); AWAIT_READY(event); ASSERT_SOME(event.get()); ASSERT_EQ(Event::HEARTBEAT, event.get().get().type()); driver.stop(); driver.join(); }
namespace master { // TODO(benh): Add units after constants. // TODO(benh): Also make configuration options be constants. // TODO(vinod): Move constants that are only used in flags to // 'master/flags.hpp'. // TODO(jieyu): Use static functions for all the constants. See more // details in MESOS-1023. // Maximum number of slot offers to have outstanding for each framework. constexpr int MAX_OFFERS_PER_FRAMEWORK = 50; // Minimum number of cpus per offer. constexpr double MIN_CPUS = 0.01; // Minimum amount of memory per offer. constexpr Bytes MIN_MEM = Megabytes(32); // Default interval the master uses to send heartbeats to an HTTP // scheduler. constexpr Duration DEFAULT_HEARTBEAT_INTERVAL = Seconds(15); // Amount of time within which a slave PING should be received. // NOTE: The slave uses these PING constants to determine when // the master has stopped sending pings. If these are made // configurable, then we'll need to rely on upper/lower bounds // to ensure that the slave is not unnecessarily triggering // re-registrations. constexpr Duration DEFAULT_AGENT_PING_TIMEOUT = Seconds(15); // Maximum number of ping timeouts until slave is considered failed. constexpr size_t DEFAULT_MAX_AGENT_PING_TIMEOUTS = 5; // The minimum timeout that can be used by a newly elected leader to // allow re-registration of slaves. Any slaves that do not re-register // within this timeout will be marked unreachable; if/when the agent // re-registers, non-partition-aware tasks running on the agent will // be terminated. constexpr Duration MIN_AGENT_REREGISTER_TIMEOUT = Minutes(10); // Default limit on the percentage of slaves that will be removed // after recovering if no re-registration attempts were made. // TODO(bmahler): There's no value here that works for all setups. // Currently the default is 100% which is favorable to those running // small clusters or experimenting with Mesos. However, it's important // that we also prevent the catastrophic 100% removal case for // production clusters. This TODO is to provide a --production flag // which would allow flag defaults that are more appropriate for // production use-cases. constexpr double RECOVERY_AGENT_REMOVAL_PERCENT_LIMIT = 1.0; // 100%. // Maximum number of removed slaves to store in the cache. constexpr size_t MAX_REMOVED_SLAVES = 100000; // Default maximum number of completed frameworks to store in the cache. constexpr size_t DEFAULT_MAX_COMPLETED_FRAMEWORKS = 50; // Default maximum number of completed tasks per framework // to store in the cache. constexpr size_t DEFAULT_MAX_COMPLETED_TASKS_PER_FRAMEWORK = 1000; // Default maximum number of unreachable tasks per framework // to store in the cache. constexpr size_t DEFAULT_MAX_UNREACHABLE_TASKS_PER_FRAMEWORK = 1000; // Time interval to check for updated watchers list. constexpr Duration WHITELIST_WATCH_INTERVAL = Seconds(5); // Default number of tasks (limit) for /master/tasks endpoint. constexpr size_t TASK_LIMIT = 100; constexpr Duration DEFAULT_REGISTRY_GC_INTERVAL = Minutes(15); constexpr Duration DEFAULT_REGISTRY_MAX_AGENT_AGE = Weeks(2); constexpr size_t DEFAULT_REGISTRY_MAX_AGENT_COUNT = 100 * 1024; /** * Label used by the Leader Contender and Detector. * * \deprecated Will be deprecated as of Mesos 0.24: see MESOS-2340. */ constexpr char MASTER_INFO_LABEL[] = "info"; /** * Label used by the Leader Contender and Detector, for JSON content. * * \since Mesos 0.23 (see MESOS-2340). */ constexpr char MASTER_INFO_JSON_LABEL[] = "json.info"; // Timeout used for ZooKeeper related operations. // TODO(vinod): Master detector/contender should use this timeout. constexpr Duration ZOOKEEPER_SESSION_TIMEOUT = Seconds(10); // Name of the default, CRAM-MD5 authenticator. constexpr char DEFAULT_AUTHENTICATOR[] = "crammd5"; // Name of the default, HierarchicalDRF authenticator. constexpr char DEFAULT_ALLOCATOR[] = "HierarchicalDRF"; // The default interval between allocations. constexpr Duration DEFAULT_ALLOCATION_INTERVAL = Seconds(1); // Name of the default, local authorizer. constexpr char DEFAULT_AUTHORIZER[] = "local"; // Name of the master HTTP authentication realm for read-only endpoints. constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "mesos-master-readonly"; // Name of the master HTTP authentication realm for read-write endpoints. constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "mesos-master-readwrite"; // Name of the default authentication realm for HTTP frameworks. constexpr char DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM[] = "mesos-master-scheduler"; // Agents older than this version are not allowed to register. const Version MINIMUM_AGENT_VERSION = Version(1, 0, 0); std::vector<MasterInfo::Capability> MASTER_CAPABILITIES(); } // namespace master {
namespace slave { // TODO(jieyu): Use static functions for all the constants. See more // details in MESOS-1023. constexpr Duration EXECUTOR_REGISTRATION_TIMEOUT = Minutes(1); constexpr Duration EXECUTOR_REREGISTRATION_TIMEOUT = Seconds(2); // The maximum timeout within which an executor can re-register. // Note that this value has to be << 'MIN_AGENT_REREGISTER_TIMEOUT' // declared in 'master/constants.hpp'; since agent recovery will only // complete after this timeout has elapsed, this ensures that the // agent can re-register with the master before it is marked // unreachable and its tasks are transitioned to TASK_UNREACHABLE or // TASK_LOST. constexpr Duration MAX_EXECUTOR_REREGISTRATION_TIMEOUT = Seconds(15); // The default amount of time to wait for the executor to // shut down before destroying the container. constexpr Duration DEFAULT_EXECUTOR_SHUTDOWN_GRACE_PERIOD = Seconds(5); constexpr Duration RECOVERY_TIMEOUT = Minutes(15); // TODO(gkleiman): Move this to a different file once `TaskStatusUpdateManager` // uses `StatusUpdateManagerProcess`. See MESOS-8296. constexpr Duration STATUS_UPDATE_RETRY_INTERVAL_MIN = Seconds(10); constexpr Duration STATUS_UPDATE_RETRY_INTERVAL_MAX = Minutes(10); // Default backoff interval used by the slave to wait before registration. constexpr Duration DEFAULT_REGISTRATION_BACKOFF_FACTOR = Seconds(1); // The maximum interval the slave waits before retrying registration. // Note that this value has to be << 'MIN_SLAVE_REREGISTER_TIMEOUT' // declared in 'master/constants.hpp'. This helps the slave to retry // (re-)registration multiple times between when the master finishes // recovery and when it times out slave re-registration. constexpr Duration REGISTER_RETRY_INTERVAL_MAX = Minutes(1); // The maximum interval the slave waits before retrying authentication. constexpr Duration AUTHENTICATION_RETRY_INTERVAL_MAX = Minutes(1); // Default backoff interval used by the slave to wait after failed // authentication. constexpr Duration DEFAULT_AUTHENTICATION_BACKOFF_FACTOR = Seconds(1); constexpr Duration GC_DELAY = Weeks(1); constexpr Duration DISK_WATCH_INTERVAL = Minutes(1); // Minimum free disk capacity enforced by the garbage collector. constexpr double GC_DISK_HEADROOM = 0.1; // Maximum number of completed frameworks to store in memory. constexpr size_t MAX_COMPLETED_FRAMEWORKS = 50; // Default maximum number of completed executors per framework // to store in memory. constexpr size_t DEFAULT_MAX_COMPLETED_EXECUTORS_PER_FRAMEWORK = 150; // Maximum number of completed tasks per executor to store in memory. // // NOTE: This should be greater than zero because the agent looks // for completed tasks to determine (with false positives) whether // an executor ever received tasks. See MESOS-8411. // // TODO(mzhu): Remove this note once we can determine whether an // executor ever received tasks without looking through the // completed tasks. constexpr size_t MAX_COMPLETED_TASKS_PER_EXECUTOR = 200; // Default cpus offered by the slave. constexpr double DEFAULT_CPUS = 1; // Default memory offered by the slave. constexpr Bytes DEFAULT_MEM = Gigabytes(1); // Default disk space offered by the slave. constexpr Bytes DEFAULT_DISK = Gigabytes(10); // Default ports range offered by the slave. constexpr char DEFAULT_PORTS[] = "[31000-32000]"; // Default cpu resource given to a command executor. constexpr double DEFAULT_EXECUTOR_CPUS = 0.1; // Default memory resource given to a command executor. constexpr Bytes DEFAULT_EXECUTOR_MEM = Megabytes(32); #ifdef ENABLE_PORT_MAPPING_ISOLATOR // Default number of ephemeral ports allocated to a container by the // network isolator. constexpr uint16_t DEFAULT_EPHEMERAL_PORTS_PER_CONTAINER = 1024; #endif // Default UNIX socket (Linux) or Named Pipe (Windows) resource that provides // CLI access to the Docker daemon. #ifdef __WINDOWS__ constexpr char DEFAULT_DOCKER_HOST_RESOURCE[] = "//./pipe/docker_engine"; #else constexpr char DEFAULT_DOCKER_HOST_RESOURCE[] = "/var/run/docker.sock"; #endif // __WINDOWS__ // Default duration that docker containers will be removed after exit. constexpr Duration DOCKER_REMOVE_DELAY = Hours(6); // Default duration to wait before retry inspecting a docker // container. constexpr Duration DOCKER_INSPECT_DELAY = Seconds(1); // Default maximum number of docker inspect calls docker ps will invoke // in parallel to prevent hitting system's open file descriptor limit. constexpr size_t DOCKER_PS_MAX_INSPECT_CALLS = 100; // Default duration that docker containerizer will wait to check // docker version. // TODO(tnachen): Make this a flag. constexpr Duration DOCKER_VERSION_WAIT_TIMEOUT = Seconds(5); // Additional duration that docker containerizer will wait beyond the // configured `docker_stop_timeout` for docker stop to succeed, before // trying to kill the process by itself. constexpr Duration DOCKER_FORCE_KILL_TIMEOUT = Seconds(1); // Name of the default, CRAM-MD5 authenticatee. constexpr char DEFAULT_AUTHENTICATEE[] = "crammd5"; // Name of the default, local authorizer. constexpr char DEFAULT_AUTHORIZER[] = "local"; // Name of the agent HTTP authentication realm for read-only endpoints. constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readonly"; // Name of the agent HTTP authentication realm for read-write endpoints. constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readwrite"; // Name of the agent HTTP authentication realm for HTTP executors. constexpr char EXECUTOR_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-executor"; // Default maximum storage space to be used by the fetcher cache. constexpr Bytes DEFAULT_FETCHER_CACHE_SIZE = Gigabytes(2); // If no pings received within this timeout, then the slave will // trigger a re-detection of the master to cause a re-registration. Duration DEFAULT_MASTER_PING_TIMEOUT(); // Name of the executable for default executor. #ifdef __WINDOWS__ constexpr char MESOS_DEFAULT_EXECUTOR[] = "mesos-default-executor.exe"; #else constexpr char MESOS_DEFAULT_EXECUTOR[] = "mesos-default-executor"; #endif // __WINDOWS__ // Virtual path on which agent logs are mounted in `/files/` endpoint. constexpr char AGENT_LOG_VIRTUAL_PATH[] = "/slave/log"; std::vector<SlaveInfo::Capability> AGENT_CAPABILITIES(); } // namespace slave {