예제 #1
0
def get_all_tasks_from_state(
        mesos_state: MesosState,
        include_orphans: bool = False) -> Sequence[MesosTask]:
    """Given a mesos state, find the tasks from all frameworks.
    :param mesos_state: the mesos_state
    :returns: a list of tasks
    """
    tasks = [
        task for framework in mesos_state.get("frameworks", [])
        for task in framework.get("tasks", [])
    ]
    if include_orphans:
        tasks += mesos_state.get("orphan_tasks", [])
    return tasks
예제 #2
0
def has_registered_slaves(mesos_state: MesosState, ) -> bool:
    """ Return a boolean indicating if there are any slaves registered
    to the master according to the mesos state.
    :param mesos_state: the mesos state from the master
    :returns: a boolean, indicating if there are > 0 slaves
    """
    return len(mesos_state.get("slaves", [])) > 0
예제 #3
0
def get_resource_utilization_by_grouping(
    grouping_func: Callable[..., _KeyFuncRetT],
    mesos_state: MesosState,
    filters: List[Callable]=[],
    sort_func=None,
) -> Dict[_KeyFuncRetT, ResourceUtilizationDict]:
    """ Given a function used to group slaves and mesos state, calculate
    resource utilization for each value of a given attribute.

    :grouping_func: a function that given a slave, will return the value of an
    attribute to group by.
    :param mesos_state: the mesos state
    :param filters: filters to apply to the slaves in the calculation, with
    filtering preformed by filter_slaves
    :returns: a dict of {attribute_value: resource_usage}, where resource usage
    is the dict returned by ``calculate_resource_utilization_for_slaves`` for
    slaves grouped by attribute value.
    """
    slaves = mesos_state.get('slaves', [])
    slaves = filter_slaves(slaves, filters)
    if not has_registered_slaves(mesos_state):
        raise ValueError("There are no slaves registered in the mesos state.")

    tasks = get_all_tasks_from_state(mesos_state, include_orphans=True)
    non_terminal_tasks = [task for task in tasks if not is_task_terminal(task)]
    slave_groupings = group_slaves_by_key_func(grouping_func, slaves, sort_func)

    return {
        attribute_value: calculate_resource_utilization_for_slaves(
            slaves=slaves,
            tasks=filter_tasks_for_slaves(slaves, non_terminal_tasks),
        )
        for attribute_value, slaves in slave_groupings.items()
    }
예제 #4
0
async def get_mesos_task_count_by_slave(
    mesos_state: MesosState,
    slaves_list: Sequence[Dict]=None,
    pool: Optional[str]=None,
) -> List[Dict]:
    """Get counts of running tasks per mesos slave. Also include separate count of chronos tasks

    :param mesos_state: mesos state dict
    :param slaves_list: a list of slave dicts to count running tasks for.
    :param pool: pool of slaves to return (None means all)
    :returns: list of slave dicts {'task_count': SlaveTaskCount}
    """
    all_mesos_tasks = await get_all_running_tasks()  # empty string = all app ids
    slaves = {
        slave['id']: {'count': 0, 'slave': slave, 'batch_count': 0} for slave in mesos_state.get('slaves', [])
    }
    for task in all_mesos_tasks:
        try:
            task_slave = await task.slave()
            if task_slave['id'] not in slaves:
                log.debug("Slave {} not found for task".format(task_slave['id']))
                continue
            else:
                slaves[task_slave['id']]['count'] += 1
                task_framework = await task.framework()
                log.debug(f"Task framework: {task_framework.name}")
                # Marathon is only framework that runs service. Others are batch.
                if not task_framework.name.startswith(MARATHON_FRAMEWORK_NAME_PREFIX):
                    slaves[task_slave['id']]['batch_count'] += 1
        except SlaveDoesNotExist:
            log.debug("Tried to get mesos slaves for task {}, but none existed.".format(task['id']))
            continue
    if slaves_list:
        for slave in slaves_list:
            slave['task_counts'] = SlaveTaskCount(**slaves[slave['task_counts'].slave['id']])
        slaves_with_counts = list(slaves_list)
    elif pool:
        slaves_with_counts = [
            {'task_counts': SlaveTaskCount(**slave_counts)} for slave_counts in slaves.values()
            if slave_counts['slave']['attributes'].get('pool', 'default') == pool
        ]
    else:
        slaves_with_counts = [{'task_counts': SlaveTaskCount(**slave_counts)} for slave_counts in slaves.values()]
    for slave in slaves_with_counts:
        log.debug("Slave: {}, running {} tasks, "
                  "including {} chronos tasks".format(
                      slave['task_counts'].slave['hostname'],
                      slave['task_counts'].count,
                      slave['task_counts'].batch_count,
                  ))
    return slaves_with_counts