Пример #1
0
def tasks_blocking_by_node_id(node_id):
    api = api_from_models()

    # README(shep): Using last_checkin attr for agent-health
    timestamp = int(time.time())
    args = {'node_id': node_id, 'key': 'last_checkin', 'value': timestamp}
    r = api.attr_create(args)
    #DB does not hit updater, so we need to notify
    generic._update_transaction_id('nodes', id_list=[node_id])
    generic._update_transaction_id('attrs', id_list=[r['id']])
    task = api.task_get_first_by_query("node_id=%d and state='pending'" %
                                       int(node_id))

    # README(shep): moving this out of a while loop, to let agent-health work
    semaphore = 'task-for-%s' % node_id
    flask.current_app.logger.debug('waiting on %s' % semaphore)
    utility.wait(semaphore)
    task = api.task_get_first_by_query("node_id=%d and state='pending'" %
                                       int(node_id))
    if task:
        utility.clear(semaphore)
        result = flask.jsonify({'task': task})
    else:
        result = generic.http_notfound(msg='no task found')
    return result
Пример #2
0
def object_by_id(object_type, object_id):
    s_obj = singularize(object_type)

    api = api_from_models()
    if flask.request.method == 'PUT':
        # we just updated something, poke any waiters
        model_object = api._model_update_by_id(object_type, object_id,
                                               flask.request.json)

        _notify(model_object, object_type, object_id)

        return http_response(200, '%s Updated' % s_obj.capitalize(),
                             **{s_obj: model_object})
    elif flask.request.method == 'DELETE':
        try:
            if api._model_delete_by_id(object_type, object_id):
                return http_response(200, '%s deleted' % s_obj.capitalize())
            _notify(None, object_type, object_id)
        except exceptions.IdNotFound:
            return http_notfound(msg='not found')
    elif flask.request.method == 'GET':
        if 'poll' in flask.request.args:
            # we're polling
            semaphore = '%s-id-%s' % (object_type, object_id)
            utility.wait(semaphore)

        try:
            model_object = api._model_get_by_id(object_type, object_id)
        except exceptions.IdNotFound:
            return http_notfound(msg='not found')

        return http_response(200, 'success', **{s_obj: model_object})
    else:
        return http_notfound(msg='Unknown method %s' % flask.request.method)
Пример #3
0
            def f(session_key, txid):
                """
                Accepts a transaction id, and returns a list of
                updated nodes from input transaction_id to latest
                transaction_id.  transaction dict.

                FIXME: As an optimization, the changes could be
                accumulated in a single set up until the point
                that someone got a new txid.  Then we could avoid
                having a long list of one-element transactions, and
                instead only create db version intervals on the intervals
                that we know people could possibly refer from.  If that
                makes sense.

                Arguments:
                txid -- transaction id (opaque)

                Returns:

                session_key -- unique session key

                nodes -- list of updated node_ids from trx_id to
                latest transaction id
                """

                trans = self.transactions[what]
                current_txid = time.time()

                if session_key != self.transactions['session_key']:
                    return generic.http_response(410, 'Invalid session_key')

                txid = float(txid)

                if 'poll' in request.args:
                    # we'll poll if we have no changes
                    if txid >= max(trans.keys()):
                        semaphore = '%s-changes' % (what)
                        utility.wait(semaphore)

                if txid < min(trans.keys()):
                    return generic.http_response(410, 'Expired transaction id')

                retval = set([])
                for x in [trans[tx] for tx in trans.keys() if tx > txid]:
                    retval = retval.union(x)

                return generic.http_response(
                    200, 'Updated %s' % what.title(),
                    **{"transaction": {'session_key': session_key,
                                       'txid': '%.6f' % current_txid},
                       what: list(retval)})
Пример #4
0
def tasks_blocking_by_node_id(node_id):
    api = api_from_models()

    # README(shep): Using last_checkin attr for agent-health
    timestamp = int(time.time())
    args = {'node_id': node_id, 'key': 'last_checkin', 'value': timestamp}
    try:
        r = api.attr_create(args)
    except exceptions.IdNotFound:
        message = 'Node %s not found.' % args['node_id']
        return generic.http_notfound(msg=message)
    except exceptions.IdInvalid:
        return generic.http_badrequest()
    #DB does not hit updater, so we need to notify
    generic._update_transaction_id('nodes', id_list=[node_id])
    generic._update_transaction_id('attrs', id_list=[r['id']])

    while True:
        task = api.task_get_first_by_query("node_id=%d and state='pending'" %
                                           int(node_id))
        if task is None:
            semaphore = 'task-for-%s' % node_id
            flask.current_app.logger.debug('waiting on %s' % semaphore)
            if not utility.wait(semaphore):
                flask.current_app.logger.error("ERROR ON WAIT")
                # utility.clear(semaphore)
                return generic.http_notfound(msg='no task found')
            else:
                flask.current_app.logger.error("SUCCESS ON WAIT")
        else:
            # utility.clear(semaphore)
            return generic.http_response(task=task)
Пример #5
0
            def f(session_key, txid):
                """
                Accepts a transaction id, and returns a list of
                updated nodes from input transaction_id to latest
                transaction_id.  transaction dict.

                FIXME: As an optimization, the changes could be
                accumulated in a single set up until the point
                that someone got a new txid.  Then we could avoid
                having a long list of one-element transactions, and
                instead only create db version intervals on the intervals
                that we know people could possibly refer from.  If that
                makes sense.

                Arguments:
                txid -- transaction id (opaque)

                Returns:

                session_key -- unique session key

                nodes -- list of updated node_ids from trx_id to
                latest transaction id
                """

                trans = self.transactions[what]
                current_txid = time.time()

                if session_key != self.transactions['session_key']:
                    return generic.http_response(410, 'Invalid session_key')

                txid = float(txid)

                if 'poll' in request.args:
                    # we'll poll if we have no changes
                    if txid >= max(trans.keys()):
                        semaphore = '%s-changes' % (what)
                        utility.wait(semaphore)

                if txid < min(trans.keys()):
                    return generic.http_response(410, 'Expired transaction id')

                retval = set()
                for x in (trans[tx] for tx in trans.keys() if tx > txid):
                    retval.update(x)
                #tenant start
                #target_tenant = 'test2-tenant' #Temporary
                #log("start")
                target_tenant = request.headers.get('tenant')
                if what == 'nodes' and not generic.is_adminTenant(target_tenant):

                    try:
                        node_objects = get_objectlist_not_reserved_tenant(target_tenant)

                        remove_ids = set()

                        for node_id in retval:
                            for obj in node_objects:
                                #self._logger.debug('obj = %s' % obj)
                                if int(node_id) == obj['id']:
                                    #self._logger.debug('obj = %s' % obj)
                                    remove_ids.add(node_id)
                                    break
                    
                        retval.difference_update(remove_ids)

                    except Invalid_Key:
                        retval = set()
                #log("end")
                #tenant end

                return generic.http_response(
                    200, 'Updated %s' % what.title(),
                    **{"transaction": {'session_key': session_key,
                                       'txid': '%.6f' % current_txid},
                       what: list(retval)})