Пример #1
0
def perform_command(command, service, instance, cluster, verbose, soa_dir, app_id=None, delta=None):
    """Performs a start/stop/restart/status on an instance
    :param command: String of start, stop, restart, status
    :param service: service name
    :param instance: instance name, like "main" or "canary"
    :param cluster: cluster name
    :param verbose: int verbosity level
    :returns: A unix-style return code
    """
    system_config = load_system_paasta_config()

    marathon_config = marathon_tools.load_marathon_config()
    job_config = marathon_tools.load_marathon_service_config(service, instance, cluster, soa_dir=soa_dir)
    if not app_id:
        try:
            app_id = job_config.format_marathon_app_dict()['id']
        except NoDockerImageError:
            job_id = compose_job_id(service, instance)
            print "Docker image for %s not in deployments.json. Exiting. Has Jenkins deployed it?" % job_id
            return 1

    normal_instance_count = job_config.get_instances()
    normal_smartstack_count = marathon_tools.get_expected_instance_count_for_namespace(service, instance, cluster)
    proxy_port = marathon_tools.get_proxy_port_for_instance(service, instance, cluster, soa_dir=soa_dir)

    client = marathon_tools.get_marathon_client(marathon_config.get_url(), marathon_config.get_username(),
                                                marathon_config.get_password())
    if command == 'restart':
        restart_marathon_job(service, instance, app_id, client, cluster)
    elif command == 'status':
        print status_desired_state(service, instance, client, job_config)
        print status_marathon_job(service, instance, app_id, normal_instance_count, client)
        tasks, out = status_marathon_job_verbose(service, instance, client)
        if verbose > 0:
            print out
        print status_mesos_tasks(service, instance, normal_instance_count)
        if verbose > 0:
            tail_lines = calculate_tail_lines(verbose_level=verbose)
            print status_mesos_tasks_verbose(
                job_id=app_id,
                get_short_task_id=get_short_task_id,
                tail_lines=tail_lines,
            )
        if proxy_port is not None:
            print status_smartstack_backends(
                service=service,
                instance=instance,
                cluster=cluster,
                job_config=job_config,
                tasks=tasks,
                expected_count=normal_smartstack_count,
                soa_dir=soa_dir,
                verbose=verbose > 0,
                synapse_port=system_config.get_synapse_port(),
                synapse_haproxy_url_format=system_config.get_synapse_haproxy_url_format(),
            )
    else:
        # The command parser shouldn't have let us get this far...
        raise NotImplementedError("Command %s is not implemented!" % command)
    return 0
Пример #2
0
def perform_command(command, service, instance, cluster, verbose, soa_dir, app_id=None, delta=None):
    """Performs a start/stop/restart/status on an instance
    :param command: String of start, stop, restart, status
    :param service: service name
    :param instance: instance name, like "main" or "canary"
    :param cluster: cluster name
    :param verbose: int verbosity level
    :returns: A unix-style return code
    """
    system_config = load_system_paasta_config()

    marathon_config = marathon_tools.load_marathon_config()
    job_config = marathon_tools.load_marathon_service_config(service, instance, cluster, soa_dir=soa_dir)
    if not app_id:
        try:
            app_id = job_config.format_marathon_app_dict()['id']
        except NoDockerImageError:
            job_id = compose_job_id(service, instance)
            print "Docker image for %s not in deployments.json. Exiting. Has Jenkins deployed it?" % job_id
            return 1

    normal_instance_count = job_config.get_instances()
    normal_smartstack_count = marathon_tools.get_expected_instance_count_for_namespace(service, instance, cluster)
    proxy_port = marathon_tools.get_proxy_port_for_instance(service, instance, cluster, soa_dir=soa_dir)

    client = marathon_tools.get_marathon_client(marathon_config.get_url(), marathon_config.get_username(),
                                                marathon_config.get_password())
    if command == 'restart':
        restart_marathon_job(service, instance, app_id, client, cluster)
    elif command == 'status':
        print status_desired_state(service, instance, client, job_config)
        print status_marathon_job(service, instance, app_id, normal_instance_count, client)
        tasks, out = status_marathon_job_verbose(service, instance, client)
        if verbose > 0:
            print out
        print status_mesos_tasks(service, instance, normal_instance_count)
        if verbose > 0:
            tail_lines = calculate_tail_lines(verbose_level=verbose)
            print status_mesos_tasks_verbose(
                job_id=app_id,
                get_short_task_id=get_short_task_id,
                tail_lines=tail_lines,
            )
        if proxy_port is not None:
            print status_smartstack_backends(
                service=service,
                instance=instance,
                cluster=cluster,
                job_config=job_config,
                tasks=tasks,
                expected_count=normal_smartstack_count,
                soa_dir=soa_dir,
                verbose=verbose > 0,
                synapse_port=system_config.get_synapse_port(),
                synapse_haproxy_url_format=system_config.get_synapse_haproxy_url_format(),
            )
    else:
        # The command parser shouldn't have let us get this far...
        raise NotImplementedError("Command %s is not implemented!" % command)
    return 0
Пример #3
0
def perform_command(command, service, instance, cluster, verbose, soa_dir, app_id=None, delta=None):
    """Performs a start/stop/restart/status/scale on an instance
    :param command: String of start, stop, restart, status or scale
    :param service: service name
    :param instance: instance name, like "main" or "canary"
    :param cluster: cluster name
    :param verbose: bool if the output should be verbose or not
    :returns: A unix-style return code
    """
    marathon_config = marathon_tools.load_marathon_config()
    job_config = marathon_tools.load_marathon_service_config(service, instance, cluster, soa_dir=soa_dir)
    if not app_id:
        try:
            app_id = marathon_tools.create_complete_config(service, instance, marathon_config, soa_dir=soa_dir)['id']
        except NoDockerImageError:
            job_id = compose_job_id(service, instance)
            print "Docker image for %s not in deployments.json. Exiting. Has Jenkins deployed it?" % job_id
            return 1

    normal_instance_count = job_config.get_instances()
    normal_smartstack_count = marathon_tools.get_expected_instance_count_for_namespace(service, instance)
    proxy_port = marathon_tools.get_proxy_port_for_instance(service, instance, soa_dir=soa_dir)

    client = marathon_tools.get_marathon_client(marathon_config.get_url(), marathon_config.get_username(),
                                                marathon_config.get_password())
    if command == 'start':
        start_marathon_job(service, instance, app_id, normal_instance_count, client, cluster)
    elif command == 'stop':
        stop_marathon_job(service, instance, app_id, client, cluster)
    elif command == 'restart':
        restart_marathon_job(service, instance, app_id, normal_instance_count, client, cluster)
    elif command == 'status':
        # Setting up transparent cache for http API calls
        requests_cache.install_cache('paasta_serviceinit', backend='memory')

        print status_desired_state(service, instance, client, job_config)
        print status_marathon_job(service, instance, app_id, normal_instance_count, client)
        tasks, out = status_marathon_job_verbose(service, instance, client)
        if verbose:
            print out
        print status_mesos_tasks(service, instance, normal_instance_count)
        if verbose:
            print status_mesos_tasks_verbose(app_id, get_short_task_id)
        if proxy_port is not None:
            print status_smartstack_backends(
                service=service,
                instance=instance,
                cluster=cluster,
                job_config=job_config,
                tasks=tasks,
                expected_count=normal_smartstack_count,
                soa_dir=soa_dir,
                verbose=verbose,
            )
    elif command == 'scale':
        scale_marathon_job(service, instance, app_id, delta, client, cluster)
    else:
        # The command parser shouldn't have let us get this far...
        raise NotImplementedError("Command %s is not implemented!" % command)
    return 0
Пример #4
0
def test_status_mesos_tasks_verbose():
    with contextlib.nested(
        mock.patch("paasta_tools.mesos_tools.get_running_tasks_from_active_frameworks", autospec=True),
        mock.patch("paasta_tools.mesos_tools.get_non_running_tasks_from_active_frameworks", autospec=True),
        mock.patch("paasta_tools.mesos_tools.format_running_mesos_task_row", autospec=True),
        mock.patch("paasta_tools.mesos_tools.format_non_running_mesos_task_row", autospec=True),
    ) as (
        get_running_mesos_tasks_patch,
        get_non_running_mesos_tasks_patch,
        format_running_mesos_task_row_patch,
        format_non_running_mesos_task_row_patch,
    ):
        get_running_mesos_tasks_patch.return_value = ["doing a lap"]
        get_non_running_mesos_tasks_patch.return_value = ["eating a burrito"]
        format_running_mesos_task_row_patch.return_value = ["id", "host", "mem", "cpu", "time"]
        format_non_running_mesos_task_row_patch.return_value = ["id", "host", "time", "state"]
        job_id = (format_job_id("fake_service", "fake_instance"),)

        def get_short_task_id(_):
            return "short_task_id"

        actual = mesos_tools.status_mesos_tasks_verbose(job_id, get_short_task_id)
        assert "Running Tasks" in actual
        assert "Non-Running Tasks" in actual
        format_running_mesos_task_row_patch.assert_called_once_with("doing a lap", get_short_task_id)
        format_non_running_mesos_task_row_patch.assert_called_once_with("eating a burrito", get_short_task_id)
Пример #5
0
def test_status_mesos_tasks_verbose():
    with contextlib.nested(
        mock.patch('paasta_tools.mesos_tools.get_running_tasks_from_active_frameworks', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.get_non_running_tasks_from_active_frameworks', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.format_running_mesos_task_row', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.format_non_running_mesos_task_row', autospec=True,),
    ) as (
        get_running_mesos_tasks_patch,
        get_non_running_mesos_tasks_patch,
        format_running_mesos_task_row_patch,
        format_non_running_mesos_task_row_patch,
    ):
        get_running_mesos_tasks_patch.return_value = ['doing a lap']
        get_non_running_mesos_tasks_patch.return_value = ['eating a burrito']
        format_running_mesos_task_row_patch.return_value = ['id', 'host', 'mem', 'cpu', 'disk', 'time']
        format_non_running_mesos_task_row_patch.return_value = ['id', 'host', 'time', 'state']
        job_id = format_job_id('fake_service', 'fake_instance'),

        def get_short_task_id(_):
            return 'short_task_id'

        actual = mesos_tools.status_mesos_tasks_verbose(job_id, get_short_task_id)
        assert 'Running Tasks' in actual
        assert 'Non-Running Tasks' in actual
        format_running_mesos_task_row_patch.assert_called_once_with('doing a lap', get_short_task_id)
        format_non_running_mesos_task_row_patch.assert_called_once_with('eating a burrito', get_short_task_id)
Пример #6
0
def format_chronos_job_status(job, running_tasks, verbose):
    """Given a job, returns a pretty-printed human readable output regarding
    the status of the job.

    :param job: dictionary of the job status
    :param running_tasks: a list of Mesos tasks associated with ``job``, e.g. the
                          result of ``mesos_tools.get_running_tasks_from_active_frameworks()``.

    """
    config_hash = _format_config_hash(job)
    disabled_state = _format_disabled_status(job)
    (last_result, formatted_time) = _format_last_result(job)
    schedule = _format_schedule(job)
    command = _format_command(job)
    mesos_status = _format_mesos_status(job, running_tasks)
    if verbose:
        mesos_status_verbose = status_mesos_tasks_verbose(job["name"], get_short_task_id)
        mesos_status = "%s\n%s" % (mesos_status, mesos_status_verbose)
    return (
        "Config:     %(config_hash)s\n"
        "  Status:   %(disabled_state)s\n"
        "  Last:     %(last_result)s (%(formatted_time)s)\n"
        "  Schedule: %(schedule)s\n"
        "  Command:  %(command)s\n"
        "  Mesos:    %(mesos_status)s" % {
            "config_hash": config_hash,
            "disabled_state": disabled_state,
            "last_result": last_result,
            "formatted_time": formatted_time,
            "schedule": schedule,
            "command": command,
            "mesos_status": mesos_status,
        }
    )
Пример #7
0
def format_chronos_job_status(client, job, running_tasks, verbose=0):
    """Given a job, returns a pretty-printed human readable output regarding
    the status of the job.

    :param job: dictionary of the job status
    :param running_tasks: a list of Mesos tasks associated with ``job``, e.g. the
                          result of ``mesos_tools.get_running_tasks_from_frameworks()``.
    :param verbose: int verbosity level
    """
    job_name = _format_job_name(job)
    is_temporary = chronos_tools.is_temporary_job(
        job) if 'name' in job else 'UNKNOWN'
    job_name = modify_string_for_rerun_status(job_name, is_temporary)
    disabled_state = _format_disabled_status(job)
    service, instance = chronos_tools.decompose_job_id(job['name'])
    chronos_state = chronos_tools.get_chronos_status_for_job(
        client, service, instance)

    (last_result, formatted_time) = _format_last_result(job)

    job_type = chronos_tools.get_job_type(job)
    schedule_type = _get_schedule_field_for_job_type(job_type)
    schedule_formatter = get_schedule_formatter(job_type, verbose)
    schedule_value = schedule_formatter(job)

    command = _format_command(job)
    mesos_status = _format_mesos_status(running_tasks)
    if verbose > 0:
        tail_lines = calculate_tail_lines(verbose_level=verbose)
        mesos_status_verbose = status_mesos_tasks_verbose(
            job_id=job["name"],
            get_short_task_id=get_short_task_id,
            tail_lines=tail_lines,
        )
        mesos_status = "%s\n%s" % (mesos_status, mesos_status_verbose)
    return ("Job:     %(job_name)s\n"
            "  Status:   %(disabled_state)s (%(chronos_state)s)"
            "  Last:     %(last_result)s (%(formatted_time)s)\n"
            "  %(schedule_type)s: %(schedule_value)s\n"
            "  Command:  %(command)s\n"
            "  Mesos:    %(mesos_status)s" % {
                "job_name": job_name,
                "is_temporary": is_temporary,
                "schedule_type": schedule_type,
                "chronos_state": PaastaColors.grey(chronos_state),
                "disabled_state": disabled_state,
                "last_result": last_result,
                "formatted_time": formatted_time,
                "schedule_value": schedule_value,
                "command": command,
                "mesos_status": mesos_status,
            })
Пример #8
0
def format_chronos_job_status(client, job, running_tasks, verbose=0):
    """Given a job, returns a pretty-printed human readable output regarding
    the status of the job.

    :param job: dictionary of the job status
    :param running_tasks: a list of Mesos tasks associated with ``job``, e.g. the
                          result of ``mesos_tools.get_running_tasks_from_active_frameworks()``.
    :param verbose: int verbosity level
    """
    job_name = _format_job_name(job)
    is_temporary = chronos_tools.is_temporary_job(job) if 'name' in job else 'UNKNOWN'
    job_name = modify_string_for_rerun_status(job_name, is_temporary)
    disabled_state = _format_disabled_status(job)
    service, instance = chronos_tools.decompose_job_id(job['name'])
    chronos_state = chronos_tools.get_chronos_status_for_job(client, service, instance)

    (last_result, formatted_time) = _format_last_result(job)

    job_type = chronos_tools.get_job_type(job)
    schedule_type = _get_schedule_field_for_job_type(job_type)
    schedule_formatter = get_schedule_formatter(job_type, verbose)
    schedule_value = schedule_formatter(job)

    command = _format_command(job)
    mesos_status = _format_mesos_status(job, running_tasks)
    if verbose > 0:
        tail_lines = calculate_tail_lines(verbose_level=verbose)
        mesos_status_verbose = status_mesos_tasks_verbose(
            job_id=job["name"],
            get_short_task_id=get_short_task_id,
            tail_lines=tail_lines,
        )
        mesos_status = "%s\n%s" % (mesos_status, mesos_status_verbose)
    return (
        "Job:     %(job_name)s\n"
        "  Status:   %(disabled_state)s (%(chronos_state)s)"
        "  Last:     %(last_result)s (%(formatted_time)s)\n"
        "  %(schedule_type)s: %(schedule_value)s\n"
        "  Command:  %(command)s\n"
        "  Mesos:    %(mesos_status)s" % {
            "job_name": job_name,
            "is_temporary": is_temporary,
            "schedule_type": schedule_type,
            "chronos_state": PaastaColors.grey(chronos_state),
            "disabled_state": disabled_state,
            "last_result": last_result,
            "formatted_time": formatted_time,
            "schedule_value": schedule_value,
            "command": command,
            "mesos_status": mesos_status,
        }
    )
Пример #9
0
def perform_command(command, service, instance, cluster, verbose, soa_dir):
    tail_lines = calculate_tail_lines(verbose_level=verbose)

    # We have to add a spacer at the end to make sure we only return
    # things for service.main and not service.main_foo
    task_id_prefix = "{}{}".format(compose_job_id(service, instance), MESOS_TASK_SPACER)

    if command == 'status':
        paasta_print(status_mesos_tasks_verbose(
            job_id=task_id_prefix,
            get_short_task_id=lambda x: x,
            tail_lines=tail_lines,
        ))
Пример #10
0
def test_status_mesos_tasks_verbose(test_case):
    tail_lines, expected_format_tail_call_count = test_case
    with contextlib.nested(
        mock.patch('paasta_tools.mesos_tools.get_running_tasks_from_active_frameworks', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.get_non_running_tasks_from_active_frameworks', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.format_running_mesos_task_row', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.format_non_running_mesos_task_row', autospec=True,),
        mock.patch('paasta_tools.mesos_tools.format_stdstreams_tail_for_task', autospec=True,),
    ) as (
        get_running_mesos_tasks_patch,
        get_non_running_mesos_tasks_patch,
        format_running_mesos_task_row_patch,
        format_non_running_mesos_task_row_patch,
        format_stdstreams_tail_for_task_patch,
    ):
        get_running_mesos_tasks_patch.return_value = ['doing a lap']

        template_task_return = {
            'statuses': [{'timestamp': '##########'}],
            'state': 'NOT_RUNNING',
        }
        non_running_mesos_tasks = []
        for _ in xrange(15):  # excercise the code that sorts/truncates the list of non running tasks
            task_return = template_task_return.copy()
            task_return['statuses'][0]['timestamp'] = str(1457109986 + random.randrange(-60 * 60 * 24, 60 * 60 * 24))
            non_running_mesos_tasks.append(task_return)
        get_non_running_mesos_tasks_patch.return_value = non_running_mesos_tasks

        format_running_mesos_task_row_patch.return_value = ['id', 'host', 'mem', 'cpu', 'time']
        format_non_running_mesos_task_row_patch.return_value = ['id', 'host', 'time', 'state']
        format_stdstreams_tail_for_task_patch.return_value = ['tail']
        job_id = format_job_id('fake_service', 'fake_instance'),

        def get_short_task_id(_):
            return 'short_task_id'

        actual = mesos_tools.status_mesos_tasks_verbose(
            job_id=job_id,
            get_short_task_id=get_short_task_id,
            tail_lines=tail_lines,
        )
        assert 'Running Tasks' in actual
        assert 'Non-Running Tasks' in actual
        format_running_mesos_task_row_patch.assert_called_once_with('doing a lap', get_short_task_id)
        assert format_non_running_mesos_task_row_patch.call_count == 10  # maximum n of tasks we display
        assert format_stdstreams_tail_for_task_patch.call_count == expected_format_tail_call_count
Пример #11
0
def test_status_mesos_tasks_verbose(test_case):
    tail_lines, expected_format_tail_call_count = test_case
    filter_string = format_job_id('fake_service', 'fake_instance')

    with asynctest.patch(
        'paasta_tools.mesos_tools.get_cached_list_of_running_tasks_from_frameworks', autospec=True,
        return_value=[{'id': filter_string}],
    ), asynctest.patch(
        'paasta_tools.mesos_tools.get_cached_list_of_not_running_tasks_from_frameworks', autospec=True,
    ) as get_cached_list_of_not_running_tasks_from_frameworks_patch, asynctest.patch(
        'paasta_tools.mesos_tools.format_running_mesos_task_row', autospec=True,
    ) as format_running_mesos_task_row_patch, asynctest.patch(
        'paasta_tools.mesos_tools.format_non_running_mesos_task_row', autospec=True,
    ) as format_non_running_mesos_task_row_patch, asynctest.patch(
        'paasta_tools.mesos_tools.format_stdstreams_tail_for_task', autospec=True,
    ) as format_stdstreams_tail_for_task_patch:

        template_task_return = {
            'id': filter_string,
            'statuses': [{'timestamp': '##########'}],
            'state': 'NOT_RUNNING',
        }
        non_running_mesos_tasks = []
        for _ in range(15):  # excercise the code that sorts/truncates the list of non running tasks
            task_return = template_task_return.copy()
            task_return['statuses'][0]['timestamp'] = str(1457109986 + random.randrange(-60 * 60 * 24, 60 * 60 * 24))
            non_running_mesos_tasks.append(task_return)
        get_cached_list_of_not_running_tasks_from_frameworks_patch.return_value = non_running_mesos_tasks

        format_running_mesos_task_row_patch.return_value = ['id', 'host', 'mem', 'cpu', 'time']
        format_non_running_mesos_task_row_patch.return_value = ['id', 'host', 'time', 'state']
        format_stdstreams_tail_for_task_patch.return_value = ['tail']

        actual = mesos_tools.status_mesos_tasks_verbose(
            filter_string=filter_string,
            get_short_task_id=mock.sentinel.get_short_task_id,
            tail_lines=tail_lines,
        )
        assert 'Running Tasks' in actual
        assert 'Non-Running Tasks' in actual
        format_running_mesos_task_row_patch.assert_called_once_with(
            {'id': filter_string},
            mock.sentinel.get_short_task_id,
        )
        assert format_non_running_mesos_task_row_patch.call_count == 10  # maximum n of tasks we display
        assert format_stdstreams_tail_for_task_patch.call_count == expected_format_tail_call_count
Пример #12
0
def test_status_mesos_tasks_verbose():
    with contextlib.nested(
            mock.patch(
                'paasta_tools.mesos_tools.get_running_tasks_from_active_frameworks',
                autospec=True,
            ),
            mock.patch(
                'paasta_tools.mesos_tools.get_non_running_tasks_from_active_frameworks',
                autospec=True,
            ),
            mock.patch(
                'paasta_tools.mesos_tools.format_running_mesos_task_row',
                autospec=True,
            ),
            mock.patch(
                'paasta_tools.mesos_tools.format_non_running_mesos_task_row',
                autospec=True,
            ),
    ) as (
            get_running_mesos_tasks_patch,
            get_non_running_mesos_tasks_patch,
            format_running_mesos_task_row_patch,
            format_non_running_mesos_task_row_patch,
    ):
        get_running_mesos_tasks_patch.return_value = ['doing a lap']
        get_non_running_mesos_tasks_patch.return_value = ['eating a burrito']
        format_running_mesos_task_row_patch.return_value = [
            'id', 'host', 'mem', 'cpu', 'time'
        ]
        format_non_running_mesos_task_row_patch.return_value = [
            'id', 'host', 'time', 'state'
        ]
        job_id = format_job_id('fake_service', 'fake_instance'),

        def get_short_task_id(_):
            return 'short_task_id'

        actual = mesos_tools.status_mesos_tasks_verbose(
            job_id, get_short_task_id)
        assert 'Running Tasks' in actual
        assert 'Non-Running Tasks' in actual
        format_running_mesos_task_row_patch.assert_called_once_with(
            'doing a lap', get_short_task_id)
        format_non_running_mesos_task_row_patch.assert_called_once_with(
            'eating a burrito', get_short_task_id)
Пример #13
0
def status_mesos_tasks(
    service: str,
    instance: str,
    normal_instance_count: int,
    verbose: int,
) -> str:
    job_id = marathon_tools.format_job_id(service, instance)
    # We have to add a spacer at the end to make sure we only return
    # things for service.main and not service.main_foo
    filter_string = f"{job_id}{marathon_tools.MESOS_TASK_SPACER}"

    try:
        count = len(
            select_tasks_by_id(
                a_sync.block(get_cached_list_of_running_tasks_from_frameworks),
                filter_string))
        if count >= normal_instance_count:
            status = PaastaColors.green("Healthy")
            count_str = PaastaColors.green("(%d/%d)" %
                                           (count, normal_instance_count))
        elif count == 0:
            status = PaastaColors.red("Critical")
            count_str = PaastaColors.red("(%d/%d)" %
                                         (count, normal_instance_count))
        else:
            status = PaastaColors.yellow("Warning")
            count_str = PaastaColors.yellow("(%d/%d)" %
                                            (count, normal_instance_count))
        running_string = PaastaColors.bold('TASK_RUNNING')
        output = f"Mesos:      {status} - {count_str} tasks in the {running_string} state."
    except ReadTimeout:
        return "Error: talking to Mesos timed out. It may be overloaded."

    if verbose > 0:
        tail_lines = calculate_tail_lines(verbose_level=verbose)
        output += '\n' + status_mesos_tasks_verbose(
            filter_string=filter_string,
            get_short_task_id=get_short_task_id,
            tail_lines=tail_lines,
        )

    return output
Пример #14
0
def test_status_mesos_tasks_verbose(test_case):
    tail_stdstreams, expected_format_tail_call_count = test_case
    with contextlib.nested(
        mock.patch("paasta_tools.mesos_tools.get_running_tasks_from_active_frameworks", autospec=True),
        mock.patch("paasta_tools.mesos_tools.get_non_running_tasks_from_active_frameworks", autospec=True),
        mock.patch("paasta_tools.mesos_tools.format_running_mesos_task_row", autospec=True),
        mock.patch("paasta_tools.mesos_tools.format_non_running_mesos_task_row", autospec=True),
        mock.patch("paasta_tools.mesos_tools.format_stdstreams_tail_for_task", autospec=True),
    ) as (
        get_running_mesos_tasks_patch,
        get_non_running_mesos_tasks_patch,
        format_running_mesos_task_row_patch,
        format_non_running_mesos_task_row_patch,
        format_stdstreams_tail_for_task_patch,
    ):
        get_running_mesos_tasks_patch.return_value = ["doing a lap"]

        template_task_return = {"statuses": [{"timestamp": "##########"}], "state": "NOT_RUNNING"}
        non_running_mesos_tasks = []
        for _ in xrange(15):  # excercise the code that sorts/truncates the list of non running tasks
            task_return = template_task_return.copy()
            task_return["statuses"][0]["timestamp"] = str(1457109986 + random.randrange(-60 * 60 * 24, 60 * 60 * 24))
            non_running_mesos_tasks.append(task_return)
        get_non_running_mesos_tasks_patch.return_value = non_running_mesos_tasks

        format_running_mesos_task_row_patch.return_value = ["id", "host", "mem", "cpu", "time"]
        format_non_running_mesos_task_row_patch.return_value = ["id", "host", "time", "state"]
        format_stdstreams_tail_for_task_patch.return_value = ["tail"]
        job_id = (format_job_id("fake_service", "fake_instance"),)

        def get_short_task_id(_):
            return "short_task_id"

        actual = mesos_tools.status_mesos_tasks_verbose(job_id, get_short_task_id, tail_stdstreams)
        assert "Running Tasks" in actual
        assert "Non-Running Tasks" in actual
        format_running_mesos_task_row_patch.assert_called_once_with("doing a lap", get_short_task_id)
        assert format_non_running_mesos_task_row_patch.call_count == 10  # maximum n of tasks we display
        assert format_stdstreams_tail_for_task_patch.call_count == expected_format_tail_call_count
Пример #15
0
def perform_command(command,
                    service,
                    instance,
                    cluster,
                    verbose,
                    soa_dir,
                    app_id=None,
                    delta=None):
    """Performs a start/stop/restart/status/scale on an instance
    :param command: String of start, stop, restart, status or scale
    :param service: service name
    :param instance: instance name, like "main" or "canary"
    :param cluster: cluster name
    :param verbose: bool if the output should be verbose or not
    :returns: A unix-style return code
    """
    marathon_config = marathon_tools.load_marathon_config()
    job_config = marathon_tools.load_marathon_service_config(service,
                                                             instance,
                                                             cluster,
                                                             soa_dir=soa_dir)
    if not app_id:
        try:
            app_id = marathon_tools.create_complete_config(
                service, instance, marathon_config, soa_dir=soa_dir)['id']
        except NoDockerImageError:
            job_id = compose_job_id(service, instance)
            print "Docker image for %s not in deployments.json. Exiting. Has Jenkins deployed it?" % job_id
            return 1

    normal_instance_count = job_config.get_instances()
    normal_smartstack_count = marathon_tools.get_expected_instance_count_for_namespace(
        service, instance)
    proxy_port = marathon_tools.get_proxy_port_for_instance(service,
                                                            instance,
                                                            soa_dir=soa_dir)

    client = marathon_tools.get_marathon_client(marathon_config.get_url(),
                                                marathon_config.get_username(),
                                                marathon_config.get_password())
    if command == 'start':
        start_marathon_job(service, instance, app_id, normal_instance_count,
                           client, cluster)
    elif command == 'stop':
        stop_marathon_job(service, instance, app_id, client, cluster)
    elif command == 'restart':
        restart_marathon_job(service, instance, app_id, normal_instance_count,
                             client, cluster)
    elif command == 'status':
        # Setting up transparent cache for http API calls
        requests_cache.install_cache('paasta_serviceinit', backend='memory')

        print status_desired_state(service, instance, client, job_config)
        print status_marathon_job(service, instance, app_id,
                                  normal_instance_count, client)
        tasks, out = status_marathon_job_verbose(service, instance, client)
        if verbose:
            print out
        print status_mesos_tasks(service, instance, normal_instance_count)
        if verbose:
            print status_mesos_tasks_verbose(app_id, get_short_task_id)
        if proxy_port is not None:
            print status_smartstack_backends(
                service=service,
                instance=instance,
                cluster=cluster,
                job_config=job_config,
                tasks=tasks,
                expected_count=normal_smartstack_count,
                soa_dir=soa_dir,
                verbose=verbose,
            )
    elif command == 'scale':
        scale_marathon_job(service, instance, app_id, delta, client, cluster)
    else:
        # The command parser shouldn't have let us get this far...
        raise NotImplementedError("Command %s is not implemented!" % command)
    return 0
Пример #16
0
def test_status_mesos_tasks_verbose(test_case):
    tail_lines, expected_format_tail_call_count = test_case
    filter_string = format_job_id("fake_service", "fake_instance")

    with asynctest.patch(
            "paasta_tools.mesos_tools.get_cached_list_of_running_tasks_from_frameworks",
            autospec=True,
            return_value=[{
                "id": filter_string
            }],
    ), asynctest.patch(
            "paasta_tools.mesos_tools.get_cached_list_of_not_running_tasks_from_frameworks",
            autospec=True,
    ) as get_cached_list_of_not_running_tasks_from_frameworks_patch, asynctest.patch(
            "paasta_tools.mesos_tools.format_running_mesos_task_row",
            autospec=True
    ) as format_running_mesos_task_row_patch, asynctest.patch(
            "paasta_tools.mesos_tools.format_non_running_mesos_task_row",
            autospec=True
    ) as format_non_running_mesos_task_row_patch, asynctest.patch(
            "paasta_tools.mesos_tools.format_stdstreams_tail_for_task",
            autospec=True) as format_stdstreams_tail_for_task_patch:

        template_task_return = {
            "id": filter_string,
            "statuses": [{
                "timestamp": "##########"
            }],
            "state": "NOT_RUNNING",
        }
        non_running_mesos_tasks = []
        for _ in range(
                15
        ):  # exercise the code that sorts/truncates the list of non running tasks
            task_return = template_task_return.copy()
            task_return["statuses"][0]["timestamp"] = str(
                1457109986 + random.randrange(-60 * 60 * 24, 60 * 60 * 24))
            non_running_mesos_tasks.append(task_return)
        get_cached_list_of_not_running_tasks_from_frameworks_patch.return_value = (
            non_running_mesos_tasks)

        format_running_mesos_task_row_patch.return_value = [
            "id",
            "host",
            "mem",
            "cpu",
            "time",
        ]
        format_non_running_mesos_task_row_patch.return_value = [
            "id",
            "host",
            "time",
            "state",
        ]
        format_stdstreams_tail_for_task_patch.return_value = ["tail"]

        actual = mesos_tools.status_mesos_tasks_verbose(
            filter_string=filter_string,
            get_short_task_id=mock.sentinel.get_short_task_id,
            tail_lines=tail_lines,
        )
        assert "Running Tasks" in actual
        assert "Non-Running Tasks" in actual
        format_running_mesos_task_row_patch.assert_called_once_with(
            {"id": filter_string}, mock.sentinel.get_short_task_id)
        assert (format_non_running_mesos_task_row_patch.call_count == 10
                )  # maximum n of tasks we display
        assert (format_stdstreams_tail_for_task_patch.call_count ==
                expected_format_tail_call_count)