Example #1
0
def main(args=None):
    print('Starting cook executor...')

    environment = os.environ
    executor_id = environment.get('MESOS_EXECUTOR_ID', '1')
    log_level = environment.get('EXECUTOR_LOG_LEVEL', 'INFO')

    logging.basicConfig(level=log_level,
                        filename='executor.log',
                        format='%(asctime)s %(levelname)s %(message)s')
    logging.info('Starting cook executor {}'.format(executor_id))
    logging.info('Log level is {}'.format(log_level))

    config = cc.initialize_config(environment)

    def handle_interrupt(interrupt_code, _):
        logging.info(
            'Received interrupt code {}, preparing to terminate executor'.
            format(interrupt_code))
        stop_signal.set()

    signal.signal(signal.SIGINT, handle_interrupt)
    signal.signal(signal.SIGTERM, handle_interrupt)

    stop_signal = Event()
    driver_thread = Thread(target=ce.run_mesos_driver,
                           args=(stop_signal, config))
    driver_thread.start()
    logging.info('Driver thread has started')
    driver_thread.join()
    logging.info('Driver thread has completed')

    exit_code = 1 if stop_signal.isSet() else 0
    logging.info('Executor exiting with code {}'.format(exit_code))
    sys.exit(exit_code)
Example #2
0
    def test_initialize_config_custom(self):
        environment = {'EXECUTOR_MAX_BYTES_READ_PER_LINE': '1234',
                       'EXECUTOR_MAX_MESSAGE_LENGTH': '1024',
                       'EXECUTOR_MEMORY_USAGE_INTERVAL_SECS': '120',
                       'EXECUTOR_PROGRESS_OUTPUT_FILE': 'progress_file',
                       'EXECUTOR_RESET_VARS': 'VAR_A,VAR_B',
                       'MESOS_CHECKPOINT': '1',
                       'MESOS_DIRECTORY': '/mesos/directory',
                       'MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD': '4secs',
                       'MESOS_RECOVERY_TIMEOUT': '5mins',
                       'MESOS_SANDBOX': '/sandbox/location',
                       'PROGRESS_REGEX_STRING': 'progress/regex',
                       'PROGRESS_SAMPLE_INTERVAL_MS': '2500'}
        config = cc.initialize_config(environment)

        self.assertEqual(True, config.checkpoint)
        self.assertEqual(1234, config.max_bytes_read_per_line)
        self.assertEqual(1024, config.max_message_length)
        self.assertEqual(120, config.memory_usage_interval_secs)
        self.assertEqual('/mesos/directory', config.mesos_directory)
        self.assertEqual('EXECUTOR_PROGRESS_OUTPUT_FILE', config.progress_output_env_variable)
        self.assertEqual('progress_file', config.progress_output_name)
        self.assertEqual('progress/regex', config.progress_regex_string)
        self.assertEqual(5 * 60 * 1000, config.recovery_timeout_ms)
        self.assertEqual(2500, config.progress_sample_interval_ms)
        self.assertEqual(['VAR_A', 'VAR_B'], config.reset_vars)
        self.assertEqual('/sandbox/location', config.sandbox_directory)
        self.assertEqual(4000, config.shutdown_grace_period_ms)
Example #3
0
    def test_initialize_config_configured_progress_file_name_is_dev_null(self):
        environment = {
            'EXECUTOR_DEFAULT_PROGRESS_OUTPUT_NAME': 'stderr_file',
            'EXECUTOR_MAX_BYTES_READ_PER_LINE': '1234',
            'EXECUTOR_MAX_MESSAGE_LENGTH': '1024',
            'EXECUTOR_PROGRESS_OUTPUT_FILE_ENV': 'OUTPUT_TARGET_FILE',
            'MESOS_EXECUTOR_ID': 'e123456',
            'MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD': '4secs',
            'MESOS_SANDBOX': '/sandbox/location',
            'OUTPUT_TARGET_FILE': '/dev/null',
            'PROGRESS_REGEX_STRING': 'progress/regex',
            'PROGRESS_SAMPLE_INTERVAL_MS': '2500'
        }
        config = cc.initialize_config(environment)

        self.assertEqual(1234, config.max_bytes_read_per_line)
        self.assertEqual(1024, config.max_message_length)
        self.assertEqual(3600, config.memory_usage_interval_secs)
        self.assertEqual('OUTPUT_TARGET_FILE',
                         config.progress_output_env_variable)
        self.assertEqual('/dev/null', config.progress_output_name)
        self.assertEqual('progress/regex', config.progress_regex_string)
        self.assertEqual(2500, config.progress_sample_interval_ms)
        self.assertEqual('/sandbox/location', config.sandbox_directory)
        self.assertEqual(4000, config.shutdown_grace_period_ms)
Example #4
0
    def test_initialize_config_defaults(self):
        environment = {}
        config = cc.initialize_config(environment)

        self.assertEqual(4 * 1024, config.max_bytes_read_per_line)
        self.assertEqual(512, config.max_message_length)
        self.assertEqual('stdout', config.progress_output_name)
        self.assertEqual('progress: (\\d*), (.*)',
                         config.progress_regex_string)
        self.assertEqual(1000, config.progress_sample_interval_ms)
        self.assertEqual('', config.sandbox_directory)
        self.assertEqual(2000, config.shutdown_grace_period_ms)
Example #5
0
    def test_initialize_config_defaults(self):
        environment = {}
        config = cc.initialize_config(environment)

        self.assertEqual(False, config.checkpoint)
        self.assertEqual(4 * 1024, config.max_bytes_read_per_line)
        self.assertEqual(512, config.max_message_length)
        self.assertEqual('', config.mesos_directory)
        self.assertEqual('executor.progress', config.progress_output_name)
        self.assertEqual('progress: ([0-9]*\\.?[0-9]+), (.*)', config.progress_regex_string)
        self.assertEqual(15 * 60 * 1000, config.recovery_timeout_ms)
        self.assertEqual(1000, config.progress_sample_interval_ms)
        self.assertEqual([], config.reset_vars)
        self.assertEqual('', config.sandbox_directory)
        self.assertEqual(2000, config.shutdown_grace_period_ms)
Example #6
0
    def test_initialize_config_custom(self):
        environment = {
            'EXECUTOR_MAX_BYTES_READ_PER_LINE': '1234',
            'EXECUTOR_MAX_MESSAGE_LENGTH': '1024',
            'MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD': '4secs',
            'MESOS_SANDBOX': '/sandbox/location',
            'PROGRESS_OUTPUT_FILE': 'progress_file',
            'PROGRESS_REGEX_STRING': 'progress/regex',
            'PROGRESS_SAMPLE_INTERVAL_MS': '2500'
        }
        config = cc.initialize_config(environment)

        self.assertEqual(1234, config.max_bytes_read_per_line)
        self.assertEqual(1024, config.max_message_length)
        self.assertEqual('progress_file', config.progress_output_name)
        self.assertEqual('progress/regex', config.progress_regex_string)
        self.assertEqual(2500, config.progress_sample_interval_ms)
        self.assertEqual('/sandbox/location', config.sandbox_directory)
        self.assertEqual(4000, config.shutdown_grace_period_ms)
Example #7
0
    def test_initialize_config_custom_progress_file_without_sandbox(self):
        environment = {'EXECUTOR_MAX_BYTES_READ_PER_LINE': '1234',
                       'EXECUTOR_MAX_MESSAGE_LENGTH': '1024',
                       'EXECUTOR_MEMORY_USAGE_INTERVAL_SECS': '20',
                       'EXECUTOR_PROGRESS_OUTPUT_FILE_ENV': 'OUTPUT_TARGET_FILE',
                       'MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD': '4secs',
                       'OUTPUT_TARGET_FILE': 'progress.out',
                       'PROGRESS_REGEX_STRING': 'progress/regex',
                       'PROGRESS_SAMPLE_INTERVAL_MS': '2500'}
        config = cc.initialize_config(environment)

        self.assertEqual(1234, config.max_bytes_read_per_line)
        self.assertEqual(1024, config.max_message_length)
        self.assertEqual(30, config.memory_usage_interval_secs)
        self.assertEqual('OUTPUT_TARGET_FILE', config.progress_output_env_variable)
        self.assertEqual('progress.out', config.progress_output_name)
        self.assertEqual('progress/regex', config.progress_regex_string)
        self.assertEqual(2500, config.progress_sample_interval_ms)
        self.assertEqual('', config.sandbox_directory)
        self.assertEqual(4000, config.shutdown_grace_period_ms)
Example #8
0
def main(args=None):
    from _version import __version__

    if len(sys.argv) == 2 and sys.argv[1] == "--version":
        print(__version__)
        sys.exit(0)

    cio.print_out('Cook Executor version {}'.format(__version__), flush=True)

    environment = os.environ
    executor_id = environment.get('MESOS_EXECUTOR_ID', '1')
    log_level = environment.get('EXECUTOR_LOG_LEVEL', 'INFO')

    logging.basicConfig(level=log_level,
                        filename='executor.log',
                        format='%(asctime)s %(levelname)s %(message)s')
    logging.info('Starting Cook Executor {} for executor-id={}'.format(
        __version__, executor_id))
    logging.info('Log level is {}'.format(log_level))

    config = cc.initialize_config(environment)

    def print_memory_usage_task():
        cu.print_memory_usage()
        timer = Timer(config.memory_usage_interval_secs,
                      print_memory_usage_task)
        timer.daemon = True
        timer.start()

    print_memory_usage_task()

    stop_signal = Event()
    non_zero_exit_signal = Event()

    def handle_interrupt(interrupt_code, _):
        logging.info(
            'Executor interrupted with code {}'.format(interrupt_code))
        cio.print_and_log(
            'Received kill for task {} with grace period of {}'.format(
                executor_id, config.shutdown_grace_period))
        stop_signal.set()
        non_zero_exit_signal.set()
        cu.print_memory_usage()

    signal.signal(signal.SIGINT, handle_interrupt)
    signal.signal(signal.SIGTERM, handle_interrupt)

    try:
        executor = ce.CookExecutor(stop_signal, config)
        driver = pm.MesosExecutorDriver(executor)

        logging.info('MesosExecutorDriver is starting...')
        driver.start()

        executor.await_completion()

        logging.info('MesosExecutorDriver requested to stop')
        driver.stop()
        logging.info('MesosExecutorDriver has been stopped')

        executor.await_disconnect()
    except Exception:
        logging.exception('Error in __main__')
        stop_signal.set()
        non_zero_exit_signal.set()

    cu.print_memory_usage()
    exit_code = 1 if non_zero_exit_signal.isSet() else 0
    logging.info('Executor exiting with code {}'.format(exit_code))
    sys.exit(exit_code)