示例#1
0
def test_task():
    task = Task(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
    need_set = set([
        "path",
        "category",
        "package",
        "timeout",
        "priority",
        "options",
        "machine",
        "platform",
        "tags",
        "custom",
        "memory",
        "clock",
        "enforce_timeout",
        "main_task_id",
        "retrieved",
        "route",
    ])
    have_set = set(dir(task))
    assert need_set & have_set == need_set
示例#2
0
    def submit_tasks(self, node_id, pend_tasks_num):

        db = session()
        node = db.query(Node).filter_by(id=node_id).first()
        if node.name != "master":
            # don't do nothing if nothing in pending
            # Get tasks from main_db submitted through web interface
            main_db_tasks = main_db.list_tasks(status=TASK_PENDING,
                                               order_by=desc("priority"))
            if main_db_tasks:
                log.debug("going to upload {} tasks to node id {}".format(
                    pend_tasks_num, node_id))
                limit = 0
                for t in main_db_tasks:

                    # convert the options string to a dict, e.g. {'opt1': 'val1', 'opt2': 'val2', 'opt3': 'val3'}
                    if "node=" in t.options:
                        try:
                            options = dict((value.strip()
                                            for value in option.split("=", 1))
                                           for option in t.options.split(","))
                            if options.get("node", node.name) != node.name:
                                # skip task
                                continue
                        except Exception as e:
                            log.error(e)
                    tasks = db.query(Task).filter_by(main_task_id=t.id).all()
                    if not tasks:
                        # Check if file exist, if no wipe from db and continue, rare cases
                        if not os.path.exists(t.target):
                            main_db.delete_task(t.id)
                            log.info(
                                "Task id: {} - File doesn't exist: {}".format(
                                    t.id, t.target))
                            continue
                        # Convert array of tags into comma separated list
                        tags = ','.join([tag.name for tag in t.tags])
                        # Append a comma, to make LIKE searches more precise
                        if tags: tags += ','
                        if "msoffice-crypt-tmp" in t.target and "password="******"password="******"pwd=")
                        args = dict(package=t.package,
                                    category=t.category,
                                    timeout=t.timeout,
                                    priority=t.priority,
                                    options=t.options +
                                    ",main_task_id={}".format(t.id),
                                    machine=t.machine,
                                    platform=t.platform,
                                    tags=tags,
                                    custom=t.custom,
                                    memory=t.memory,
                                    clock=t.clock,
                                    enforce_timeout=t.enforce_timeout,
                                    main_task_id=t.id)
                        task = Task(path=t.target, **args)
                        db.add(task)
                        try:
                            db.commit()
                        except Exception as e:
                            #main_db.set_status(t.id, TASK_FAILED_REPORTING)
                            db.rollback()
                            log.info(e)
                            continue
                        if reporting_conf.distributed.enable_tags:
                            # Only get tasks that have not been pushed yet.
                            q = db.query(Task).filter(
                                or_(Task.node_id == None,
                                    Task.task_id == None),
                                Task.finished == False)
                            # Order by task priority and task id.
                            q = q.order_by(-Task.priority, Task.main_task_id)
                            # Get available node tags
                            machines = db.query(Machine).filter_by(
                                node_id=node.id).all()

                            # Get available tag combinations
                            ta = set()
                            for m in machines:
                                for i in xrange(1, len(m.tags) + 1):
                                    for tag in combinations(m.tags, i):
                                        ta.add(','.join(tag))
                            ta = list(ta)
                            # Create filter query from tasks in ta
                            tags = [getattr(Task, "tags") == ""]
                            for tg in ta:
                                if len(tg.split(',')) == 1:
                                    tags.append(
                                        getattr(Task, "tags") == (tg + ','))
                                else:
                                    tg = tg.split(',')
                                    # ie. LIKE '%,%,%,'
                                    t_combined = [
                                        getattr(Task, "tags").like(
                                            "%s" % ('%,' * len(tg)))
                                    ]
                                    for tag in tg:
                                        t_combined.append(
                                            getattr(Task, "tags").like(
                                                "%%%s%%" % (tag + ',')))
                                    tags.append(and_(*t_combined))

                            # Filter by available tags
                            q = q.filter(or_(*tags))

                            # Submit appropriate tasks to node
                            if pend_tasks_num > 0:
                                for task in q.limit(pend_tasks_num).all():
                                    submitted = node_submit_task(
                                        task.id, node.id)
                                    if submitted:
                                        main_db.set_status(t.id, TASK_RUNNING)
                                db.close()
                                return
                        else:
                            # Submit appropriate tasks to node
                            submitted = node_submit_task(task.id, node.id)
                            if submitted:
                                main_db.set_status(t.id, TASK_RUNNING)
                            limit += 1
                            if limit == pend_tasks_num:
                                db.close()
                                return
                    else:
                        for task in tasks:
                            log.info(
                                "Deleting incorrectly uploaded file from dist db, main_task_id: {}"
                                .format(t.id))
                            db.delete(task)
                        db.commit()

        db.close()
示例#3
0
    def submit_tasks(self, node_id, pend_tasks_num, options_like=False, force_push_push=False, db=None):
        # HACK do not create a new session if the current one (passed as parameter) is still valid.
        try:
            node = db.query(Node).filter_by(name=node_id).first()
        except (OperationalError, SQLAlchemyError) as e:
            log.warning(
                "Got an operational Exception when trying to submit tasks: {}".format(e))
            return False

        limit = 0
        if node.name != "master":
            # don't do nothing if nothing in pending
            # Get tasks from main_db submitted through web interface
            main_db_tasks = main_db.list_tasks(status=TASK_PENDING, order_by=desc("priority"), options_like=options_like, limit=pend_tasks_num)
            if not main_db_tasks:
                return True
            if main_db_tasks:
                for t in main_db_tasks:
                    force_push = False
                    try:
                        # convert the options string to a dict, e.g. {'opt1': 'val1', 'opt2': 'val2', 'opt3': 'val3'}
                        options = get_options(t.options)
                        # check if node exist and its correct
                        if "node=" in t.options:
                            requested_node = options.get("node")
                            if requested_node not in STATUSES:
                                # if the requested node is not available
                                force_push = True
                            elif requested_node != node.name:
                                # otherwise keep looping
                                continue
                        if "timeout=" in t.options:
                            t.timeout = options["timeout"]
                    except Exception as e:
                        log.error(e)
                    # wtf are you doing in pendings?
                    tasks = db.query(Task).filter_by(main_task_id=t.id).all()
                    if tasks:
                        for task in tasks:
                            print(task.id, task.task_id,task.main_task_id, task.node_id)
                            #log.info("Deleting incorrectly uploaded file from dist db, main_task_id: {}".format(t.id))
                            #db.delete(task)
                            #db.commit()
                            if node.name == "master":
                                main_db.set_status(t.id, TASK_RUNNING)
                            else:
                                main_db.set_status(t.id, TASK_DISTRIBUTED)
                        continue

                    # Check if file exist, if no wipe from db and continue, rare cases
                    if t.category in ("file", "pcap", "static") and not os.path.exists(t.target):
                        log.info("Task id: {} - File doesn't exist: {}".format(t.id, t.target))
                        main_db.delete_task(t.id)
                        continue
                    # Convert array of tags into comma separated list
                    tags = ','.join([tag.name for tag in t.tags])
                    # Append a comma, to make LIKE searches more precise
                    if tags:
                        tags += ','
                    if "msoffice-crypt-tmp" in t.target and "password="******"password="******"pwd=")
                    args = dict(package=t.package, category=t.category, timeout=t.timeout, priority=t.priority,
                                options=t.options+",main_task_id={}".format(t.id), machine=t.machine, platform=t.platform,
                                tags=tags, custom=t.custom, memory=t.memory, clock=t.clock,
                                enforce_timeout=t.enforce_timeout, main_task_id=t.id)
                    task = Task(path=t.target, **args)
                    db.add(task)
                    try:
                        db.commit()
                    except Exception as e:
                        log.exception(e)
                        log.info("TASK_FAILED_REPORTING")
                        db.rollback()
                        log.info(e)
                        continue

                    if force_push or force_push_push:
                        # Submit appropriate tasks to node
                        submitted = node_submit_task(task.id, node.id)
                        if submitted:
                            if node.name == "master":
                                main_db.set_status(t.id, TASK_RUNNING)
                            else:
                                main_db.set_status(t.id, TASK_DISTRIBUTED)
                        limit += 1
                        if limit == pend_tasks_num or limit == len(main_db_tasks):
                            return True

                # Only get tasks that have not been pushed yet.
                q = db.query(Task).filter(
                    or_(Task.node_id == None, Task.task_id == None), Task.finished == False)
                if q is None:
                    return True
                # Order by task priority and task id.
                q = q.order_by(-Task.priority, Task.main_task_id)
                # if we have node set in options push
                if reporting_conf.distributed.enable_tags:
                    # Create filter query from tasks in ta
                    tags = [getattr(Task, "tags") == ""]
                    for tg in SERVER_TAGS[node.name]:
                        if len(tg.split(',')) == 1:
                            tags.append(getattr(Task, "tags") == (tg + ','))
                        else:
                            tg = tg.split(',')
                            # ie. LIKE '%,%,%,'
                            t_combined = [getattr(Task, "tags").like(
                                "%s" % ('%,' * len(tg)))]
                            for tag in tg:
                                t_combined.append(
                                    getattr(Task, "tags").like("%%%s%%" % (tag + ',')))
                            tags.append(and_(*t_combined))
                    # Filter by available tags
                    q = q.filter(or_(*tags))
                to_upload = q.limit(pend_tasks_num).all()
                if not to_upload:
                    return True
                # Submit appropriate tasks to node
                log.debug("going to upload {} tasks to node {}".format(
                    pend_tasks_num, node.name))
                for task in to_upload:
                    submitted = node_submit_task(task.id, node.id)
                    if submitted:
                        if node.name == "master":
                            main_db.set_status(task.main_task_id, TASK_RUNNING)
                        else:
                            main_db.set_status(
                                task.main_task_id, TASK_DISTRIBUTED)
                    else:
                        print(
                            "something is wrong with submission of task: {}".format(task.id))
                        db.delete(task)
                        db.commit()
                    limit += 1
                    if limit == pend_tasks_num:
                        return True
        return True